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