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 memory attachment render pass load tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktProtectedMemAttachmentLoadTests.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 AttachmentLoadTestInstance : public ProtectedTestInstance
58 {
59 public:
60 AttachmentLoadTestInstance(Context &ctx, const vk::VkClearValue &clearValue, const ValidationData &refData,
61 const ImageValidator &validator);
62 virtual tcu::TestStatus iterate(void);
63
64 private:
65 const vk::VkFormat m_imageFormat;
66 const vk::VkClearValue &m_clearValue;
67 const ValidationData &m_refData;
68 const ImageValidator &m_validator;
69 };
70
71 class AttachmentLoadTestCase : public TestCase
72 {
73 public:
AttachmentLoadTestCase(tcu::TestContext & testCtx,const std::string & name,vk::VkClearValue clearValue,ValidationData data)74 AttachmentLoadTestCase(tcu::TestContext &testCtx, const std::string &name, vk::VkClearValue clearValue,
75 ValidationData data)
76 : TestCase(testCtx, name)
77 , m_clearValue(clearValue)
78 , m_refData(data)
79 {
80 }
81
~AttachmentLoadTestCase(void)82 virtual ~AttachmentLoadTestCase(void)
83 {
84 }
createInstance(Context & ctx) const85 virtual TestInstance *createInstance(Context &ctx) const
86 {
87 return new AttachmentLoadTestInstance(ctx, m_clearValue, m_refData, m_validator);
88 }
initPrograms(vk::SourceCollections & programCollection) const89 virtual void initPrograms(vk::SourceCollections &programCollection) const
90 {
91 m_validator.initPrograms(programCollection);
92 }
checkSupport(Context & context) const93 virtual void checkSupport(Context &context) const
94 {
95 checkProtectedQueueSupport(context);
96 }
97
98 private:
99 vk::VkClearValue m_clearValue;
100 ValidationData m_refData;
101 ImageValidator m_validator;
102 };
103
AttachmentLoadTestInstance(Context & ctx,const vk::VkClearValue & clearValue,const ValidationData & refData,const ImageValidator & validator)104 AttachmentLoadTestInstance::AttachmentLoadTestInstance(Context &ctx, const vk::VkClearValue &clearValue,
105 const ValidationData &refData, const ImageValidator &validator)
106 : ProtectedTestInstance(ctx)
107 , m_imageFormat(vk::VK_FORMAT_R8G8B8A8_UNORM)
108 , m_clearValue(clearValue)
109 , m_refData(refData)
110 , m_validator(validator)
111 {
112 }
113
iterate()114 tcu::TestStatus AttachmentLoadTestInstance::iterate()
115 {
116 ProtectedContext &ctx(m_protectedContext);
117 const vk::DeviceInterface &vk = ctx.getDeviceInterface();
118 const vk::VkDevice device = ctx.getDevice();
119 const vk::VkQueue queue = ctx.getQueue();
120 const uint32_t queueFamilyIndex = ctx.getQueueFamilyIndex();
121
122 // Create output image
123 de::MovePtr<vk::ImageWithMemory> colorImage(
124 createImage2D(ctx, PROTECTION_ENABLED, queueFamilyIndex, RENDER_WIDTH, RENDER_HEIGHT, m_imageFormat,
125 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_SAMPLED_BIT));
126 vk::Unique<vk::VkImageView> colorImageView(createImageView(ctx, **colorImage, m_imageFormat));
127
128 vk::Unique<vk::VkRenderPass> renderPass(createRenderPass(ctx, m_imageFormat));
129 vk::Unique<vk::VkFramebuffer> framebuffer(
130 createFramebuffer(ctx, RENDER_WIDTH, RENDER_HEIGHT, *renderPass, *colorImageView));
131 vk::Unique<vk::VkPipelineLayout> pipelineLayout(createPipelineLayout(ctx, 0u, DE_NULL));
132
133 vk::Unique<vk::VkCommandPool> cmdPool(makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
134 vk::Unique<vk::VkCommandBuffer> cmdBuffer(
135 vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
136
137 // Begin cmd buffer
138 beginCommandBuffer(vk, *cmdBuffer);
139
140 // Start image barrier
141 {
142 const vk::VkImageMemoryBarrier startImgBarrier = {vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
143 DE_NULL, // pNext
144 0, // srcAccessMask
145 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // dstAccessMask
146 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
147 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
148 queueFamilyIndex, // srcQueueFamilyIndex
149 queueFamilyIndex, // dstQueueFamilyIndex
150 **colorImage, // image
151 {
152 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
153 0u, // baseMipLevel
154 1u, // mipLevels
155 0u, // baseArraySlice
156 1u, // subresourceRange
157 }};
158
159 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
160 (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier *)DE_NULL, 0,
161 (const vk::VkBufferMemoryBarrier *)DE_NULL, 1, &startImgBarrier);
162 }
163
164 // Image clear
165 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, vk::makeRect2D(0, 0, RENDER_WIDTH, RENDER_HEIGHT),
166 m_clearValue);
167 endRenderPass(vk, *cmdBuffer);
168
169 {
170 // Image validator reads image in compute shader
171 const vk::VkImageMemoryBarrier endImgBarrier = {vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
172 DE_NULL, // pNext
173 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask
174 vk::VK_ACCESS_SHADER_READ_BIT, // dstAccessMask
175 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout
176 vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // newLayout
177 queueFamilyIndex, // srcQueueFamilyIndex
178 queueFamilyIndex, // dstQueueFamilyIndex
179 **colorImage, // image
180 {
181 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
182 0u, // baseMipLevel
183 1u, // mipLevels
184 0u, // baseArraySlice
185 1u, // subresourceRange
186 }};
187 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
188 vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (vk::VkDependencyFlags)0, 0,
189 (const vk::VkMemoryBarrier *)DE_NULL, 0, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1,
190 &endImgBarrier);
191 }
192
193 endCommandBuffer(vk, *cmdBuffer);
194
195 // Submit command buffer
196 const vk::Unique<vk::VkFence> fence(vk::createFence(vk, device));
197 VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
198
199 // Log out test data
200 ctx.getTestContext().getLog() << tcu::TestLog::Message
201 << "Color clear value: " << tcu::Vec4(m_clearValue.color.float32)
202 << tcu::TestLog::EndMessage << tcu::TestLog::Message
203 << "Depth clear value: " << m_clearValue.depthStencil.depth
204 << tcu::TestLog::EndMessage << tcu::TestLog::Message
205 << "Stencil clear value: " << m_clearValue.depthStencil.stencil
206 << tcu::TestLog::EndMessage;
207
208 // Validate resulting image
209 if (m_validator.validateImage(ctx, m_refData, **colorImage, m_imageFormat,
210 vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL))
211 return tcu::TestStatus::pass("Everything went OK");
212 else
213 return tcu::TestStatus::fail("Something went really wrong");
214 }
215
216 } // namespace
217
createAttachmentLoadTests(tcu::TestContext & testCtx)218 tcu::TestCaseGroup *createAttachmentLoadTests(tcu::TestContext &testCtx)
219 {
220 struct
221 {
222 const vk::VkClearValue clearValue;
223 const ValidationData data;
224 } testData[] = {
225 {vk::makeClearValueColorF32(1.0f, 0.0f, 0.0f, 1.0f),
226 {{
227 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
228 tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
229 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
230 tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
231 },
232 {
233 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
234 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
235 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
236 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
237 }}},
238 {vk::makeClearValueColorF32(0.0f, 1.0f, 0.0f, 1.0f),
239 {{
240 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
241 tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
242 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
243 tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
244 },
245 {
246 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
247 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
248 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
249 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
250 }}},
251 {vk::makeClearValueColorF32(0.0f, 0.0f, 1.0f, 1.0f),
252 {{
253 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
254 tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
255 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
256 tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
257 },
258 {
259 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
260 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
261 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
262 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
263 }}},
264 {vk::makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f),
265 {{
266 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
267 tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
268 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
269 tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
270 },
271 {
272 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
273 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
274 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
275 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
276 }}},
277 {vk::makeClearValueColorF32(1.0f, 0.0f, 0.0f, 1.0f),
278 {{
279 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
280 tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
281 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
282 tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
283 },
284 {
285 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
286 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
287 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
288 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
289 }}},
290 {vk::makeClearValueColorF32(1.0f, 0.0f, 0.0f, 0.0f),
291 {{
292 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
293 tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
294 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
295 tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
296 },
297 {
298 tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
299 tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
300 tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
301 tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
302 }}},
303 {vk::makeClearValueColorF32(0.1f, 0.2f, 0.3f, 0.0f),
304 {{
305 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
306 tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
307 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),
308 tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f),
309 },
310 {
311 tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
312 tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
313 tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
314 tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
315 }}},
316 };
317
318 // Attachment Load Op Tests with static input
319 de::MovePtr<tcu::TestCaseGroup> loadStaticTests(new tcu::TestCaseGroup(testCtx, "static"));
320
321 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx)
322 {
323 const std::string name = "clear_" + de::toString(ndx + 1);
324 loadStaticTests->addChild(
325 new AttachmentLoadTestCase(testCtx, name.c_str(), testData[ndx].clearValue, testData[ndx].data));
326 }
327
328 /* Add a few randomized tests */
329 // Attachment Load Op Tests with random input
330 de::MovePtr<tcu::TestCaseGroup> loadRandomTests(new tcu::TestCaseGroup(testCtx, "random"));
331 const int testCount = 10;
332 de::Random rnd(testCtx.getCommandLine().getBaseSeed());
333 for (int ndx = 0; ndx < testCount; ++ndx)
334 {
335 const std::string name = "clear_" + de::toString(ndx + 1);
336 vk::VkClearValue clearValue = vk::makeClearValueColorVec4(tcu::randomVec4(rnd));
337 const tcu::Vec4 refValue(clearValue.color.float32[0], clearValue.color.float32[1], clearValue.color.float32[2],
338 clearValue.color.float32[3]);
339 const tcu::Vec4 vec0 = tcu::randomVec4(rnd);
340 const tcu::Vec4 vec1 = tcu::randomVec4(rnd);
341 const tcu::Vec4 vec2 = tcu::randomVec4(rnd);
342 const tcu::Vec4 vec3 = tcu::randomVec4(rnd);
343
344 ValidationData data = {{vec0, vec1, vec2, vec3}, {refValue, refValue, refValue, refValue}};
345
346 loadRandomTests->addChild(new AttachmentLoadTestCase(testCtx, name.c_str(), clearValue, data));
347 }
348
349 de::MovePtr<tcu::TestCaseGroup> loadTests(new tcu::TestCaseGroup(testCtx, "load_op"));
350 loadTests->addChild(loadStaticTests.release());
351 loadTests->addChild(loadRandomTests.release());
352 return loadTests.release();
353 }
354
355 } // namespace ProtectedMem
356 } // namespace vkt
357