1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2017 The Khronos Group Inc.
6 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Protected content clear color image tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktProtectedMemClearColorImageTests.hpp"
26
27 #include "deRandom.hpp"
28 #include "tcuTestLog.hpp"
29 #include "tcuVector.hpp"
30 #include "tcuVectorUtil.hpp"
31
32 #include "vkPrograms.hpp"
33 #include "vktTestCase.hpp"
34 #include "vktTestGroupUtil.hpp"
35 #include "vkTypeUtil.hpp"
36 #include "vkBuilderUtil.hpp"
37 #include "vkCmdUtil.hpp"
38
39 #include "vktProtectedMemContext.hpp"
40 #include "vktProtectedMemUtils.hpp"
41 #include "vktProtectedMemImageValidator.hpp"
42
43 namespace vkt
44 {
45 namespace ProtectedMem
46 {
47
48 namespace
49 {
50
51 enum
52 {
53 RENDER_WIDTH = 128,
54 RENDER_HEIGHT = 128,
55 };
56
57 class ClearColorImageTestInstance : public ProtectedTestInstance
58 {
59 public:
60 ClearColorImageTestInstance(Context &ctx, const vk::VkClearColorValue &clearColorValue,
61 const ValidationData &refData, const ImageValidator &validator,
62 const CmdBufferType cmdBufferType);
63 virtual tcu::TestStatus iterate(void);
64
65 private:
66 const vk::VkFormat m_imageFormat;
67 const vk::VkClearColorValue &m_clearColorValue;
68 const ValidationData &m_refData;
69 const ImageValidator &m_validator;
70 const CmdBufferType m_cmdBufferType;
71 };
72
73 class ClearColorImageTestCase : public TestCase
74 {
75 public:
ClearColorImageTestCase(tcu::TestContext & testCtx,const std::string & name,vk::VkClearColorValue clearColorValue,ValidationData data,CmdBufferType cmdBufferType)76 ClearColorImageTestCase(tcu::TestContext &testCtx, const std::string &name, vk::VkClearColorValue clearColorValue,
77 ValidationData data, CmdBufferType cmdBufferType)
78 : TestCase(testCtx, name)
79 , m_clearColorValue(clearColorValue)
80 , m_refData(data)
81 , m_cmdBufferType(cmdBufferType)
82 {
83 }
84
~ClearColorImageTestCase(void)85 virtual ~ClearColorImageTestCase(void)
86 {
87 }
createInstance(Context & ctx) const88 virtual TestInstance *createInstance(Context &ctx) const
89 {
90 return new ClearColorImageTestInstance(ctx, m_clearColorValue, m_refData, m_validator, m_cmdBufferType);
91 }
initPrograms(vk::SourceCollections & programCollection) const92 virtual void initPrograms(vk::SourceCollections &programCollection) const
93 {
94 m_validator.initPrograms(programCollection);
95 }
checkSupport(Context & context) const96 virtual void checkSupport(Context &context) const
97 {
98 checkProtectedQueueSupport(context);
99 #ifdef CTS_USES_VULKANSC
100 if (m_cmdBufferType == CMD_BUFFER_SECONDARY &&
101 context.getDeviceVulkanSC10Properties().secondaryCommandBufferNullOrImagelessFramebuffer == VK_FALSE)
102 TCU_THROW(NotSupportedError, "secondaryCommandBufferNullFramebuffer is not supported");
103 #endif // CTS_USES_VULKANSC
104 }
105
106 private:
107 vk::VkClearColorValue m_clearColorValue;
108 ValidationData m_refData;
109 ImageValidator m_validator;
110 CmdBufferType m_cmdBufferType;
111 };
112
ClearColorImageTestInstance(Context & ctx,const vk::VkClearColorValue & clearColorValue,const ValidationData & refData,const ImageValidator & validator,const CmdBufferType cmdBufferType)113 ClearColorImageTestInstance::ClearColorImageTestInstance(Context &ctx, const vk::VkClearColorValue &clearColorValue,
114 const ValidationData &refData, const ImageValidator &validator,
115 const CmdBufferType cmdBufferType)
116 : ProtectedTestInstance(ctx)
117 , m_imageFormat(vk::VK_FORMAT_R8G8B8A8_UNORM)
118 , m_clearColorValue(clearColorValue)
119 , m_refData(refData)
120 , m_validator(validator)
121 , m_cmdBufferType(cmdBufferType)
122 {
123 }
124
iterate()125 tcu::TestStatus ClearColorImageTestInstance::iterate()
126 {
127 ProtectedContext &ctx(m_protectedContext);
128 const vk::DeviceInterface &vk = ctx.getDeviceInterface();
129 const vk::VkDevice device = ctx.getDevice();
130 const vk::VkQueue queue = ctx.getQueue();
131 const uint32_t queueFamilyIndex = ctx.getQueueFamilyIndex();
132
133 // Create output image
134 de::MovePtr<vk::ImageWithMemory> colorImage = createImage2D(
135 ctx, PROTECTION_ENABLED, queueFamilyIndex, RENDER_WIDTH, RENDER_HEIGHT, vk::VK_FORMAT_R8G8B8A8_UNORM,
136 vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT | vk::VK_IMAGE_USAGE_SAMPLED_BIT);
137
138 vk::Unique<vk::VkPipelineLayout> pipelineLayout(createPipelineLayout(ctx, 0u, DE_NULL));
139
140 vk::Unique<vk::VkCommandPool> cmdPool(makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
141 vk::Unique<vk::VkCommandBuffer> cmdBuffer(
142 vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
143 vk::Unique<vk::VkCommandBuffer> secondaryCmdBuffer(
144 vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY));
145 vk::VkCommandBuffer targetCmdBuffer = (m_cmdBufferType == CMD_BUFFER_SECONDARY) ? *secondaryCmdBuffer : *cmdBuffer;
146
147 const vk::VkImageSubresourceRange subresourceRange = {
148 vk::VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
149 0u, // uint32_t baseMipLevel
150 1u, // uint32_t levelCount
151 0u, // uint32_t baseArrayLayer
152 1u, // uint32_t layerCount
153 };
154 // Begin cmd buffer
155 beginCommandBuffer(vk, *cmdBuffer);
156
157 if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
158 {
159 // Begin secondary command buffer
160 const vk::VkCommandBufferInheritanceInfo bufferInheritanceInfo = {
161 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, // sType
162 DE_NULL, // pNext
163 DE_NULL, // renderPass
164 0u, // subpass
165 DE_NULL, // framebuffer
166 VK_FALSE, // occlusionQueryEnable
167 (vk::VkQueryControlFlags)0u, // queryFlags
168 (vk::VkQueryPipelineStatisticFlags)0u, // pipelineStatistics
169 };
170 beginSecondaryCommandBuffer(vk, *secondaryCmdBuffer, bufferInheritanceInfo);
171 }
172
173 // Start image barrier
174 {
175 const vk::VkImageMemoryBarrier initializeBarrier = {
176 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
177 DE_NULL, // pNext
178 0, // srcAccessMask
179 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // dstAccessMask
180 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
181 vk::VK_IMAGE_LAYOUT_GENERAL, // newLayout
182 queueFamilyIndex, // srcQueueFamilyIndex
183 queueFamilyIndex, // dstQueueFamilyIndex
184 **colorImage, // image
185 subresourceRange, // subresourceRange
186 };
187
188 vk.cmdPipelineBarrier(
189 targetCmdBuffer, // commandBuffer
190 vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // srcStageMask
191 vk::VK_PIPELINE_STAGE_TRANSFER_BIT, // dstStageMask
192 (vk::VkDependencyFlags)0, // dependencyFlags
193 0, (const vk::VkMemoryBarrier *)DE_NULL, // memoryBarrierCount, pMemoryBarriers
194 0, (const vk::VkBufferMemoryBarrier *)DE_NULL, // bufferMemoryBarrierCount, pBufferMemoryBarriers
195 1, &initializeBarrier); // imageMemoryBarrierCount, pImageMemoryBarriers
196 }
197
198 // Image clear
199 vk.cmdClearColorImage(targetCmdBuffer, **colorImage, vk::VK_IMAGE_LAYOUT_GENERAL, &m_clearColorValue, 1,
200 &subresourceRange);
201
202 // Image barrier to change accessMask.
203 {
204 const vk::VkImageMemoryBarrier initializeBarrier = {
205 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
206 DE_NULL, // pNext
207 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // srcAccessMask
208 vk::VK_ACCESS_SHADER_READ_BIT, // dstAccessMask
209 vk::VK_IMAGE_LAYOUT_GENERAL, // oldLayout
210 vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // newLayout
211 queueFamilyIndex, // srcQueueFamilyIndex
212 queueFamilyIndex, // dstQueueFamilyIndex
213 **colorImage, // image
214 subresourceRange // subresourceRange
215 };
216 vk.cmdPipelineBarrier(targetCmdBuffer,
217 vk::VK_PIPELINE_STAGE_TRANSFER_BIT, // srcStageMask
218 vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, // dstStageMask
219 (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier *)DE_NULL, 0,
220 (const vk::VkBufferMemoryBarrier *)DE_NULL, 1, &initializeBarrier);
221 }
222
223 if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
224 {
225 endCommandBuffer(vk, *secondaryCmdBuffer);
226 vk.cmdExecuteCommands(*cmdBuffer, 1u, &secondaryCmdBuffer.get());
227 }
228
229 endCommandBuffer(vk, *cmdBuffer);
230
231 // Submit command buffer
232 const vk::Unique<vk::VkFence> fence(vk::createFence(vk, device));
233 VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
234
235 // Log out test data
236 ctx.getTestContext().getLog() << tcu::TestLog::Message
237 << "Color clear value: " << tcu::Vec4(m_clearColorValue.float32)
238 << tcu::TestLog::EndMessage;
239
240 // Validate resulting image
241 if (m_validator.validateImage(ctx, m_refData, **colorImage, m_imageFormat,
242 vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL))
243 return tcu::TestStatus::pass("Everything went OK");
244 else
245 return tcu::TestStatus::fail("Something went really wrong");
246 }
247
createClearColorImageTests(tcu::TestContext & testCtx,CmdBufferType cmdBufferType)248 tcu::TestCaseGroup *createClearColorImageTests(tcu::TestContext &testCtx, CmdBufferType cmdBufferType)
249 {
250 struct
251 {
252 vk::VkClearColorValue clearColorValue;
253 ValidationData data;
254 } testData[] = {
255 {{{1.0f, 0.0f, 0.0f, 1.0f}},
256 {{
257 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
258 tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
259 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
260 tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
261 },
262 {
263 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
264 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
265 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
266 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
267 }}},
268 {{{0.0f, 1.0f, 0.0f, 1.0f}},
269 {{
270 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
271 tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
272 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
273 tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
274 },
275 {
276 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
277 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
278 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
279 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
280 }}},
281 {{{0.0f, 0.0f, 1.0f, 1.0f}},
282 {{
283 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
284 tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
285 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
286 tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
287 },
288 {
289 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
290 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
291 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
292 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
293 }}},
294 {{{0.0f, 0.0f, 0.0f, 1.0f}},
295 {{
296 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
297 tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
298 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
299 tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
300 },
301 {
302 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
303 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
304 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
305 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
306 }}},
307 {{{1.0f, 0.0f, 0.0f, 1.0f}},
308 {{
309 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
310 tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
311 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
312 tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
313 },
314 {
315 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
316 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
317 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
318 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
319 }}},
320 {{{1.0f, 0.0f, 0.0f, 0.0f}},
321 {{
322 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
323 tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
324 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
325 tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
326 },
327 {
328 tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
329 tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
330 tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
331 tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
332 }}},
333 {{{0.1f, 0.2f, 0.3f, 0.0f}},
334 {{
335 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
336 tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
337 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
338 tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
339 },
340 {
341 tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
342 tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
343 tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
344 tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
345 }}},
346 };
347
348 // Clear Color Image Tests with static input
349 de::MovePtr<tcu::TestCaseGroup> clearStaticTests(new tcu::TestCaseGroup(testCtx, "static"));
350
351 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx)
352 {
353 const std::string name = "clear_" + de::toString(ndx + 1);
354 clearStaticTests->addChild(new ClearColorImageTestCase(testCtx, name.c_str(), testData[ndx].clearColorValue,
355 testData[ndx].data, cmdBufferType));
356 }
357
358 /* Add a few randomized tests */
359 // Clear Color Image Tests with random input
360 de::MovePtr<tcu::TestCaseGroup> clearRandomTests(new tcu::TestCaseGroup(testCtx, "random"));
361 const int testCount = 10;
362 de::Random rnd(testCtx.getCommandLine().getBaseSeed());
363 for (int ndx = 0; ndx < testCount; ++ndx)
364 {
365 const std::string name = "clear_" + de::toString(ndx + 1);
366 vk::VkClearValue clearValue = vk::makeClearValueColorVec4(tcu::randomVec4(rnd));
367 const tcu::Vec4 refValue(clearValue.color.float32[0], clearValue.color.float32[1], clearValue.color.float32[2],
368 clearValue.color.float32[3]);
369 const tcu::Vec4 vec0 = tcu::randomVec4(rnd);
370 const tcu::Vec4 vec1 = tcu::randomVec4(rnd);
371 const tcu::Vec4 vec2 = tcu::randomVec4(rnd);
372 const tcu::Vec4 vec3 = tcu::randomVec4(rnd);
373
374 ValidationData data = {{vec0, vec1, vec2, vec3}, {refValue, refValue, refValue, refValue}};
375 clearRandomTests->addChild(
376 new ClearColorImageTestCase(testCtx, name.c_str(), clearValue.color, data, cmdBufferType));
377 }
378
379 std::string groupName = getCmdBufferTypeStr(cmdBufferType);
380 de::MovePtr<tcu::TestCaseGroup> clearTests(new tcu::TestCaseGroup(testCtx, groupName.c_str()));
381 clearTests->addChild(clearStaticTests.release());
382 clearTests->addChild(clearRandomTests.release());
383 return clearTests.release();
384 }
385
386 } // namespace
387
createClearColorImageTests(tcu::TestContext & testCtx)388 tcu::TestCaseGroup *createClearColorImageTests(tcu::TestContext &testCtx)
389 {
390 de::MovePtr<tcu::TestCaseGroup> clearTests(new tcu::TestCaseGroup(testCtx, "clear_color"));
391
392 clearTests->addChild(createClearColorImageTests(testCtx, CMD_BUFFER_PRIMARY));
393 clearTests->addChild(createClearColorImageTests(testCtx, CMD_BUFFER_SECONDARY));
394
395 return clearTests.release();
396 }
397
398 } // namespace ProtectedMem
399 } // namespace vkt
400