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 RENDER_WIDTH = 128,
53 RENDER_HEIGHT = 128,
54 };
55
56 class ClearColorImageTestInstance : public ProtectedTestInstance
57 {
58 public:
59 ClearColorImageTestInstance (Context& ctx,
60 const vk::VkClearColorValue& clearColorValue,
61 const ValidationData& refData,
62 const ImageValidator& validator,
63 const CmdBufferType cmdBufferType);
64 virtual tcu::TestStatus iterate (void);
65
66 private:
67 const vk::VkFormat m_imageFormat;
68 const vk::VkClearColorValue& m_clearColorValue;
69 const ValidationData& m_refData;
70 const ImageValidator& m_validator;
71 const CmdBufferType m_cmdBufferType;
72 };
73
74 class ClearColorImageTestCase : public TestCase
75 {
76 public:
ClearColorImageTestCase(tcu::TestContext & testCtx,const std::string & name,vk::VkClearColorValue clearColorValue,ValidationData data,CmdBufferType cmdBufferType)77 ClearColorImageTestCase (tcu::TestContext& testCtx,
78 const std::string& name,
79 vk::VkClearColorValue clearColorValue,
80 ValidationData data,
81 CmdBufferType cmdBufferType)
82 : TestCase (testCtx, name, "Clear color image.")
83 , m_clearColorValue (clearColorValue)
84 , m_refData (data)
85 , m_cmdBufferType (cmdBufferType)
86 {
87 }
88
~ClearColorImageTestCase(void)89 virtual ~ClearColorImageTestCase (void) {}
createInstance(Context & ctx) const90 virtual TestInstance* createInstance (Context& ctx) const
91 {
92 return new ClearColorImageTestInstance(ctx, m_clearColorValue, m_refData, m_validator, m_cmdBufferType);
93 }
initPrograms(vk::SourceCollections & programCollection) const94 virtual void initPrograms (vk::SourceCollections& programCollection) const
95 {
96 m_validator.initPrograms(programCollection);
97 }
checkSupport(Context & context) const98 virtual void checkSupport (Context& context) const
99 {
100 checkProtectedQueueSupport(context);
101 #ifdef CTS_USES_VULKANSC
102 if (m_cmdBufferType == CMD_BUFFER_SECONDARY && context.getDeviceVulkanSC10Properties().secondaryCommandBufferNullOrImagelessFramebuffer == VK_FALSE)
103 TCU_THROW(NotSupportedError, "secondaryCommandBufferNullFramebuffer is not supported");
104 #endif // CTS_USES_VULKANSC
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,
114 const vk::VkClearColorValue& clearColorValue,
115 const ValidationData& refData,
116 const ImageValidator& validator,
117 const CmdBufferType cmdBufferType)
118 : ProtectedTestInstance (ctx)
119 , m_imageFormat (vk::VK_FORMAT_R8G8B8A8_UNORM)
120 , m_clearColorValue (clearColorValue)
121 , m_refData (refData)
122 , m_validator (validator)
123 , m_cmdBufferType (cmdBufferType)
124 {
125 }
126
iterate()127 tcu::TestStatus ClearColorImageTestInstance::iterate()
128 {
129 ProtectedContext& ctx (m_protectedContext);
130 const vk::DeviceInterface& vk = ctx.getDeviceInterface();
131 const vk::VkDevice device = ctx.getDevice();
132 const vk::VkQueue queue = ctx.getQueue();
133 const deUint32 queueFamilyIndex = ctx.getQueueFamilyIndex();
134
135 // Create output image
136 de::MovePtr<vk::ImageWithMemory> colorImage = createImage2D(ctx, PROTECTION_ENABLED, queueFamilyIndex,
137 RENDER_WIDTH, RENDER_HEIGHT,
138 vk::VK_FORMAT_R8G8B8A8_UNORM,
139 vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT|vk::VK_IMAGE_USAGE_SAMPLED_BIT);
140
141 vk::Unique<vk::VkPipelineLayout> pipelineLayout (createPipelineLayout(ctx, 0u, DE_NULL));
142
143 vk::Unique<vk::VkCommandPool> cmdPool (makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
144 vk::Unique<vk::VkCommandBuffer> cmdBuffer (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
145 vk::Unique<vk::VkCommandBuffer> secondaryCmdBuffer (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY));
146 vk::VkCommandBuffer targetCmdBuffer = (m_cmdBufferType == CMD_BUFFER_SECONDARY) ? *secondaryCmdBuffer : *cmdBuffer;
147
148 const vk::VkImageSubresourceRange subresourceRange =
149 {
150 vk::VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
151 0u, // uint32_t baseMipLevel
152 1u, // uint32_t levelCount
153 0u, // uint32_t baseArrayLayer
154 1u, // uint32_t layerCount
155 };
156 // Begin cmd buffer
157 beginCommandBuffer(vk, *cmdBuffer);
158
159 if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
160 {
161 // Begin secondary command buffer
162 const vk::VkCommandBufferInheritanceInfo bufferInheritanceInfo =
163 {
164 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, // sType
165 DE_NULL, // pNext
166 DE_NULL, // renderPass
167 0u, // subpass
168 DE_NULL, // framebuffer
169 VK_FALSE, // occlusionQueryEnable
170 (vk::VkQueryControlFlags)0u, // queryFlags
171 (vk::VkQueryPipelineStatisticFlags)0u, // pipelineStatistics
172 };
173 beginSecondaryCommandBuffer(vk, *secondaryCmdBuffer, bufferInheritanceInfo);
174 }
175
176 // Start image barrier
177 {
178 const vk::VkImageMemoryBarrier initializeBarrier =
179 {
180 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
181 DE_NULL, // pNext
182 0, // srcAccessMask
183 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // dstAccessMask
184 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
185 vk::VK_IMAGE_LAYOUT_GENERAL, // newLayout
186 queueFamilyIndex, // srcQueueFamilyIndex
187 queueFamilyIndex, // dstQueueFamilyIndex
188 **colorImage, // image
189 subresourceRange, // subresourceRange
190 };
191
192 vk.cmdPipelineBarrier(targetCmdBuffer, // commandBuffer
193 vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // srcStageMask
194 vk::VK_PIPELINE_STAGE_TRANSFER_BIT, // dstStageMask
195 (vk::VkDependencyFlags)0, // dependencyFlags
196 0, (const vk::VkMemoryBarrier*)DE_NULL, // memoryBarrierCount, pMemoryBarriers
197 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, // bufferMemoryBarrierCount, pBufferMemoryBarriers
198 1, &initializeBarrier); // imageMemoryBarrierCount, pImageMemoryBarriers
199 }
200
201 // Image clear
202 vk.cmdClearColorImage(targetCmdBuffer, **colorImage, vk::VK_IMAGE_LAYOUT_GENERAL, &m_clearColorValue, 1, &subresourceRange);
203
204 // Image barrier to change accessMask.
205 {
206 const vk::VkImageMemoryBarrier initializeBarrier =
207 {
208 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
209 DE_NULL, // pNext
210 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // srcAccessMask
211 vk::VK_ACCESS_SHADER_READ_BIT, // dstAccessMask
212 vk::VK_IMAGE_LAYOUT_GENERAL, // oldLayout
213 vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // newLayout
214 queueFamilyIndex, // srcQueueFamilyIndex
215 queueFamilyIndex, // dstQueueFamilyIndex
216 **colorImage, // image
217 subresourceRange // subresourceRange
218 };
219 vk.cmdPipelineBarrier(targetCmdBuffer,
220 vk::VK_PIPELINE_STAGE_TRANSFER_BIT, // srcStageMask
221 vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, // dstStageMask
222 (vk::VkDependencyFlags)0,
223 0, (const vk::VkMemoryBarrier*)DE_NULL,
224 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
225 1, &initializeBarrier);
226 }
227
228 if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
229 {
230 endCommandBuffer(vk, *secondaryCmdBuffer);
231 vk.cmdExecuteCommands(*cmdBuffer, 1u, &secondaryCmdBuffer.get());
232 }
233
234 endCommandBuffer(vk, *cmdBuffer);
235
236 // Submit command buffer
237 const vk::Unique<vk::VkFence> fence (vk::createFence(vk, device));
238 VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
239
240 // Log out test data
241 ctx.getTestContext().getLog()
242 << tcu::TestLog::Message << "Color clear value: " << tcu::Vec4(m_clearColorValue.float32) << tcu::TestLog::EndMessage;
243
244 // Validate resulting image
245 if (m_validator.validateImage(ctx, m_refData, **colorImage, m_imageFormat, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL))
246 return tcu::TestStatus::pass("Everything went OK");
247 else
248 return tcu::TestStatus::fail("Something went really wrong");
249 }
250
createClearColorImageTests(tcu::TestContext & testCtx,CmdBufferType cmdBufferType)251 tcu::TestCaseGroup* createClearColorImageTests (tcu::TestContext& testCtx, CmdBufferType cmdBufferType)
252 {
253 struct {
254 vk::VkClearColorValue clearColorValue;
255 ValidationData data;
256 } testData[] = {
257 { { { 1.0f, 0.0f, 0.0f, 1.0f } },
258 {
259 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
260 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
261 { tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
262 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), }
263 }
264 },
265 { { { 0.0f, 1.0f, 0.0f, 1.0f } },
266 {
267 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
268 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
269 { tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
270 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), }
271 }
272 },
273 { { { 0.0f, 0.0f, 1.0f, 1.0f } },
274 {
275 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
276 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
277 { tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
278 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), }
279 }
280 },
281 { { { 0.0f, 0.0f, 0.0f, 1.0f } },
282 {
283 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
284 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
285 { tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
286 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), }
287 }
288 },
289 { { { 1.0f, 0.0f, 0.0f, 1.0f } },
290 {
291 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
292 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
293 { tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
294 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), }
295 }
296 },
297 { { { 1.0f, 0.0f, 0.0f, 0.0f } },
298 {
299 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
300 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
301 { tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
302 tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), }
303 }
304 },
305 { { { 0.1f, 0.2f, 0.3f, 0.0f } },
306 {
307 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
308 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
309 { tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
310 tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), }
311 }
312 },
313 };
314
315 de::MovePtr<tcu::TestCaseGroup> clearStaticTests (new tcu::TestCaseGroup(testCtx, "static", "Clear Color Image Tests with static input"));
316
317 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx)
318 {
319 const std::string name = "clear_" + de::toString(ndx + 1);
320 clearStaticTests->addChild(new ClearColorImageTestCase(testCtx, name.c_str(), testData[ndx].clearColorValue, testData[ndx].data, cmdBufferType));
321 }
322
323 /* Add a few randomized tests */
324 de::MovePtr<tcu::TestCaseGroup> clearRandomTests (new tcu::TestCaseGroup(testCtx, "random", "Clear Color Image Tests with random input"));
325 const int testCount = 10;
326 de::Random rnd (testCtx.getCommandLine().getBaseSeed());
327 for (int ndx = 0; ndx < testCount; ++ndx)
328 {
329 const std::string name = "clear_" + de::toString(ndx + 1);
330 vk::VkClearValue clearValue = vk::makeClearValueColorVec4(tcu::randomVec4(rnd));
331 const tcu::Vec4 refValue (clearValue.color.float32[0], clearValue.color.float32[1], clearValue.color.float32[2], clearValue.color.float32[3]);
332 const tcu::Vec4 vec0 = tcu::randomVec4(rnd);
333 const tcu::Vec4 vec1 = tcu::randomVec4(rnd);
334 const tcu::Vec4 vec2 = tcu::randomVec4(rnd);
335 const tcu::Vec4 vec3 = tcu::randomVec4(rnd);
336
337 ValidationData data =
338 {
339 { vec0, vec1, vec2, vec3 },
340 { refValue, refValue, refValue, refValue }
341 };
342 clearRandomTests->addChild(new ClearColorImageTestCase(testCtx, name.c_str(), clearValue.color, data, cmdBufferType));
343 }
344
345 std::string groupName = getCmdBufferTypeStr(cmdBufferType);
346 std::string groupDesc = "Clear Color Image Tests with " + groupName + " command buffer";
347 de::MovePtr<tcu::TestCaseGroup> clearTests (new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupDesc.c_str()));
348 clearTests->addChild(clearStaticTests.release());
349 clearTests->addChild(clearRandomTests.release());
350 return clearTests.release();
351 }
352
353 } // anonymous
354
createClearColorImageTests(tcu::TestContext & testCtx)355 tcu::TestCaseGroup* createClearColorImageTests (tcu::TestContext& testCtx)
356 {
357 de::MovePtr<tcu::TestCaseGroup> clearTests (new tcu::TestCaseGroup(testCtx, "clear_color", "Clear Color Image Tests"));
358
359 clearTests->addChild(createClearColorImageTests(testCtx, CMD_BUFFER_PRIMARY));
360 clearTests->addChild(createClearColorImageTests(testCtx, CMD_BUFFER_SECONDARY));
361
362 return clearTests.release();
363 }
364
365 } // ProtectedMem
366 } // vkt
367