1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2023 LunarG, Inc.
6 * Copyright (c) 2023 Nintendo
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 Shader Object Link Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktShaderObjectRenderingTests.hpp"
26 #include "deUniquePtr.hpp"
27 #include "tcuTestCase.hpp"
28 #include "vktTestCase.hpp"
29 #include "vkCmdUtil.hpp"
30 #include "vkImageUtil.hpp"
31 #include "vktShaderObjectCreateUtil.hpp"
32 #include "vkObjUtil.hpp"
33 #include "deRandom.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkBarrierUtil.hpp"
36 #include "tcuTextureUtil.hpp"
37 #include "tcuImageCompare.hpp"
38 #include "tcuVectorUtil.hpp"
39 #include <cmath>
40
41 namespace vkt
42 {
43 namespace ShaderObject
44 {
45
46 namespace
47 {
48
49 enum ExtraAttachments
50 {
51 NONE = 0,
52 BEFORE,
53 BETWEEN,
54 AFTER,
55 };
56
57 enum DummyRenderPass
58 {
59 DUMMY_NONE = 0,
60 DUMMY_DYNAMIC,
61 DUMMY_STATIC,
62 };
63
64 struct TestParams
65 {
66 uint32_t colorAttachmentCount;
67 uint32_t extraAttachmentCount;
68 ExtraAttachments extraAttachments;
69 uint32_t extraFragmentOutputCount;
70 ExtraAttachments extraOutputs;
71 bool useDepthAttachment;
72 vk::VkFormat colorFormat;
73 vk::VkFormat depthFormat;
74 bool bindShadersBeforeBeginRendering;
75 DummyRenderPass dummyRenderPass;
76 bool writeGlFragDepth;
77 bool randomColorFormats;
78 };
79
80 const vk::VkFormat colorFormats[] = {
81 vk::VK_FORMAT_R4G4_UNORM_PACK8,
82 vk::VK_FORMAT_R4G4B4A4_UNORM_PACK16,
83 vk::VK_FORMAT_B4G4R4A4_UNORM_PACK16,
84 vk::VK_FORMAT_R5G6B5_UNORM_PACK16,
85 vk::VK_FORMAT_B5G6R5_UNORM_PACK16,
86 vk::VK_FORMAT_R5G5B5A1_UNORM_PACK16,
87 vk::VK_FORMAT_B5G5R5A1_UNORM_PACK16,
88 vk::VK_FORMAT_A1R5G5B5_UNORM_PACK16,
89 vk::VK_FORMAT_R8_UNORM,
90 vk::VK_FORMAT_R8_SNORM,
91 vk::VK_FORMAT_R8_USCALED,
92 vk::VK_FORMAT_R8_SSCALED,
93 vk::VK_FORMAT_R8_UINT,
94 vk::VK_FORMAT_R8_SINT,
95 vk::VK_FORMAT_R8_SRGB,
96 vk::VK_FORMAT_R8G8_UNORM,
97 vk::VK_FORMAT_R8G8_SNORM,
98 vk::VK_FORMAT_R8G8_USCALED,
99 vk::VK_FORMAT_R8G8_SSCALED,
100 vk::VK_FORMAT_R8G8_UINT,
101 vk::VK_FORMAT_R8G8_SINT,
102 vk::VK_FORMAT_R8G8_SRGB,
103 vk::VK_FORMAT_R8G8B8_UNORM,
104 vk::VK_FORMAT_R8G8B8_SNORM,
105 vk::VK_FORMAT_R8G8B8_USCALED,
106 vk::VK_FORMAT_R8G8B8_SSCALED,
107 vk::VK_FORMAT_R8G8B8_UINT,
108 vk::VK_FORMAT_R8G8B8_SINT,
109 vk::VK_FORMAT_R8G8B8_SRGB,
110 vk::VK_FORMAT_B8G8R8_UNORM,
111 vk::VK_FORMAT_B8G8R8_SNORM,
112 vk::VK_FORMAT_B8G8R8_USCALED,
113 vk::VK_FORMAT_B8G8R8_SSCALED,
114 vk::VK_FORMAT_B8G8R8_UINT,
115 vk::VK_FORMAT_B8G8R8_SINT,
116 vk::VK_FORMAT_B8G8R8_SRGB,
117 vk::VK_FORMAT_R8G8B8A8_UNORM,
118 vk::VK_FORMAT_R8G8B8A8_SNORM,
119 vk::VK_FORMAT_R8G8B8A8_USCALED,
120 vk::VK_FORMAT_R8G8B8A8_SSCALED,
121 vk::VK_FORMAT_R8G8B8A8_UINT,
122 vk::VK_FORMAT_R8G8B8A8_SINT,
123 vk::VK_FORMAT_R8G8B8A8_SRGB,
124 vk::VK_FORMAT_B8G8R8A8_UNORM,
125 vk::VK_FORMAT_B8G8R8A8_SNORM,
126 vk::VK_FORMAT_B8G8R8A8_USCALED,
127 vk::VK_FORMAT_B8G8R8A8_SSCALED,
128 vk::VK_FORMAT_B8G8R8A8_UINT,
129 vk::VK_FORMAT_B8G8R8A8_SINT,
130 vk::VK_FORMAT_B8G8R8A8_SRGB,
131 vk::VK_FORMAT_A8B8G8R8_UNORM_PACK32,
132 vk::VK_FORMAT_A8B8G8R8_SNORM_PACK32,
133 vk::VK_FORMAT_A8B8G8R8_USCALED_PACK32,
134 vk::VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
135 vk::VK_FORMAT_A8B8G8R8_UINT_PACK32,
136 vk::VK_FORMAT_A8B8G8R8_SINT_PACK32,
137 vk::VK_FORMAT_A8B8G8R8_SRGB_PACK32,
138 vk::VK_FORMAT_A2R10G10B10_UNORM_PACK32,
139 vk::VK_FORMAT_A2R10G10B10_SNORM_PACK32,
140 vk::VK_FORMAT_A2R10G10B10_USCALED_PACK32,
141 vk::VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
142 vk::VK_FORMAT_A2R10G10B10_UINT_PACK32,
143 vk::VK_FORMAT_A2R10G10B10_SINT_PACK32,
144 vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32,
145 vk::VK_FORMAT_A2B10G10R10_SNORM_PACK32,
146 vk::VK_FORMAT_A2B10G10R10_USCALED_PACK32,
147 vk::VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
148 vk::VK_FORMAT_A2B10G10R10_UINT_PACK32,
149 vk::VK_FORMAT_A2B10G10R10_SINT_PACK32,
150 vk::VK_FORMAT_R16_UNORM,
151 vk::VK_FORMAT_R16_SNORM,
152 vk::VK_FORMAT_R16_USCALED,
153 vk::VK_FORMAT_R16_SSCALED,
154 vk::VK_FORMAT_R16_UINT,
155 vk::VK_FORMAT_R16_SINT,
156 vk::VK_FORMAT_R16_SFLOAT,
157 vk::VK_FORMAT_R16G16_UNORM,
158 vk::VK_FORMAT_R16G16_SNORM,
159 vk::VK_FORMAT_R16G16_USCALED,
160 vk::VK_FORMAT_R16G16_SSCALED,
161 vk::VK_FORMAT_R16G16_UINT,
162 vk::VK_FORMAT_R16G16_SINT,
163 vk::VK_FORMAT_R16G16_SFLOAT,
164 vk::VK_FORMAT_R16G16B16_UNORM,
165 vk::VK_FORMAT_R16G16B16_SNORM,
166 vk::VK_FORMAT_R16G16B16_USCALED,
167 vk::VK_FORMAT_R16G16B16_SSCALED,
168 vk::VK_FORMAT_R16G16B16_UINT,
169 vk::VK_FORMAT_R16G16B16_SINT,
170 vk::VK_FORMAT_R16G16B16_SFLOAT,
171 vk::VK_FORMAT_R16G16B16A16_UNORM,
172 vk::VK_FORMAT_R16G16B16A16_SNORM,
173 vk::VK_FORMAT_R16G16B16A16_USCALED,
174 vk::VK_FORMAT_R16G16B16A16_SSCALED,
175 vk::VK_FORMAT_R16G16B16A16_UINT,
176 vk::VK_FORMAT_R16G16B16A16_SINT,
177 vk::VK_FORMAT_R16G16B16A16_SFLOAT,
178 vk::VK_FORMAT_R32_UINT,
179 vk::VK_FORMAT_R32_SINT,
180 vk::VK_FORMAT_R32_SFLOAT,
181 vk::VK_FORMAT_R32G32_UINT,
182 vk::VK_FORMAT_R32G32_SINT,
183 vk::VK_FORMAT_R32G32_SFLOAT,
184 vk::VK_FORMAT_R32G32B32_UINT,
185 vk::VK_FORMAT_R32G32B32_SINT,
186 vk::VK_FORMAT_R32G32B32_SFLOAT,
187 vk::VK_FORMAT_R32G32B32A32_UINT,
188 vk::VK_FORMAT_R32G32B32A32_SINT,
189 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
190 };
191
192 const vk::VkFormat randomColorFormats[] = {
193 vk::VK_FORMAT_R8_UNORM,
194 vk::VK_FORMAT_R8_SNORM,
195 vk::VK_FORMAT_R8G8_UNORM,
196 vk::VK_FORMAT_R8G8_SNORM,
197 vk::VK_FORMAT_R8G8B8A8_UNORM,
198 vk::VK_FORMAT_R8G8B8A8_SNORM,
199 vk::VK_FORMAT_A8B8G8R8_UNORM_PACK32,
200 vk::VK_FORMAT_A8B8G8R8_SNORM_PACK32,
201 vk::VK_FORMAT_R16_UNORM,
202 vk::VK_FORMAT_R16_SNORM,
203 vk::VK_FORMAT_R16G16_UNORM,
204 vk::VK_FORMAT_R16G16_SNORM,
205 vk::VK_FORMAT_R16G16_SFLOAT,
206 vk::VK_FORMAT_R16G16B16_UNORM,
207 vk::VK_FORMAT_R16G16B16_SNORM,
208 vk::VK_FORMAT_R16G16B16_SFLOAT,
209 vk::VK_FORMAT_R16G16B16A16_UNORM,
210 vk::VK_FORMAT_R16G16B16A16_SNORM,
211 vk::VK_FORMAT_R16G16B16A16_SFLOAT,
212 vk::VK_FORMAT_R32_SFLOAT,
213 vk::VK_FORMAT_R32G32_SFLOAT,
214 vk::VK_FORMAT_R32G32B32_SFLOAT,
215 vk::VK_FORMAT_R32G32B32A32_SFLOAT,
216 };
217
readDepthAttachment(const vk::DeviceInterface & vk,vk::VkDevice device,vk::VkQueue queue,uint32_t queueFamilyIndex,vk::Allocator & allocator,vk::VkImage image,vk::VkFormat format,const tcu::UVec2 & renderSize,vk::VkImageLayout currentLayout)218 de::MovePtr<tcu::TextureLevel> readDepthAttachment(const vk::DeviceInterface &vk, vk::VkDevice device,
219 vk::VkQueue queue, uint32_t queueFamilyIndex,
220 vk::Allocator &allocator, vk::VkImage image, vk::VkFormat format,
221 const tcu::UVec2 &renderSize, vk::VkImageLayout currentLayout)
222 {
223 vk::Move<vk::VkBuffer> buffer;
224 de::MovePtr<vk::Allocation> bufferAlloc;
225 vk::Move<vk::VkCommandPool> cmdPool;
226 vk::Move<vk::VkCommandBuffer> cmdBuffer;
227
228 tcu::TextureFormat retFormat(tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST);
229 tcu::TextureFormat bufferFormat(tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST);
230 const vk::VkImageAspectFlags barrierAspect =
231 vk::VK_IMAGE_ASPECT_DEPTH_BIT |
232 (mapVkFormat(format).order == tcu::TextureFormat::DS ? vk::VK_IMAGE_ASPECT_STENCIL_BIT :
233 (vk::VkImageAspectFlagBits)0);
234
235 switch (format)
236 {
237 case vk::VK_FORMAT_D16_UNORM:
238 case vk::VK_FORMAT_D16_UNORM_S8_UINT:
239 bufferFormat.type = retFormat.type = tcu::TextureFormat::UNORM_INT16;
240 break;
241 case vk::VK_FORMAT_D24_UNORM_S8_UINT:
242 case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
243 retFormat.type = tcu::TextureFormat::UNORM_INT24;
244 // vkCmdCopyBufferToImage copies D24 data to 32-bit pixels.
245 bufferFormat.type = tcu::TextureFormat::UNSIGNED_INT_24_8_REV;
246 break;
247 case vk::VK_FORMAT_D32_SFLOAT:
248 case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
249 bufferFormat.type = retFormat.type = tcu::TextureFormat::FLOAT;
250 break;
251 default:
252 TCU_FAIL("unrecognized format");
253 }
254
255 const vk::VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * bufferFormat.getPixelSize();
256 de::MovePtr<tcu::TextureLevel> resultLevel(new tcu::TextureLevel(retFormat, renderSize.x(), renderSize.y()));
257
258 // Create destination buffer
259 {
260 const vk::VkBufferCreateInfo bufferParams = {
261 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
262 DE_NULL, // const void* pNext;
263 0u, // VkBufferCreateFlags flags;
264 pixelDataSize, // VkDeviceSize size;
265 vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
266 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
267 0u, // uint32_t queueFamilyIndexCount;
268 DE_NULL // const uint32_t* pQueueFamilyIndices;
269 };
270
271 buffer = createBuffer(vk, device, &bufferParams);
272 bufferAlloc =
273 allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), vk::MemoryRequirement::HostVisible);
274 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
275 }
276
277 // Create command pool and buffer
278 cmdPool = createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
279 cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
280
281 beginCommandBuffer(vk, *cmdBuffer);
282 copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()),
283 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, currentLayout, 1u, barrierAspect,
284 vk::VK_IMAGE_ASPECT_DEPTH_BIT);
285 endCommandBuffer(vk, *cmdBuffer);
286
287 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
288
289 // Read buffer data
290 invalidateAlloc(vk, device, *bufferAlloc);
291 tcu::copy(*resultLevel,
292 tcu::ConstPixelBufferAccess(bufferFormat, resultLevel->getSize(), bufferAlloc->getHostPtr()));
293
294 return resultLevel;
295 }
296
297 class ShaderObjectRenderingInstance : public vkt::TestInstance
298 {
299 public:
ShaderObjectRenderingInstance(Context & context,const TestParams & params)300 ShaderObjectRenderingInstance(Context &context, const TestParams ¶ms)
301 : vkt::TestInstance(context)
302 , m_params(params)
303 {
304 }
~ShaderObjectRenderingInstance(void)305 virtual ~ShaderObjectRenderingInstance(void)
306 {
307 }
308
309 tcu::TestStatus iterate(void) override;
310
311 private:
312 void beginRendering(vk::VkCommandBuffer cmdBuffer);
313 void createDummyImage(void);
314 void createDummyRenderPass(void);
315 void setColorFormats(const vk::InstanceDriver &vki);
316 void generateExpectedImage(const tcu::PixelBufferAccess &outputImage, const uint32_t width, const uint32_t height,
317 uint32_t attachmentIndex);
318
319 TestParams m_params;
320
321 const vk::VkRect2D m_renderArea = vk::makeRect2D(0, 0, 32, 32);
322 std::vector<vk::VkFormat> m_colorFormats;
323 std::vector<vk::Move<vk::VkImageView>> m_colorImageViews;
324 vk::Move<vk::VkImageView> m_depthImageView;
325
326 de::MovePtr<vk::ImageWithMemory> m_dummyImage;
327 vk::Move<vk::VkImageView> m_dummyImageView;
328 vk::Move<vk::VkRenderPass> m_dummyRenderPass;
329 vk::Move<vk::VkFramebuffer> m_dummyFramebuffer;
330 };
331
createDummyImage(void)332 void ShaderObjectRenderingInstance::createDummyImage(void)
333 {
334 const vk::DeviceInterface &vk = m_context.getDeviceInterface();
335 const vk::VkDevice device = m_context.getDevice();
336 auto &alloc = m_context.getDefaultAllocator();
337 const auto colorSubresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
338
339 vk::VkFormat format = m_params.colorFormat == vk::VK_FORMAT_R8G8B8A8_UNORM ? vk::VK_FORMAT_R32G32B32A32_SFLOAT :
340 vk::VK_FORMAT_R8G8B8A8_UNORM;
341
342 const vk::VkImageCreateInfo createInfo = {
343 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
344 DE_NULL, // const void* pNext
345 0u, // VkImageCreateFlags flags
346 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
347 format, // VkFormat format
348 {32, 32, 1}, // VkExtent3D extent
349 1u, // uint32_t mipLevels
350 1u, // uint32_t arrayLayers
351 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
352 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
353 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
354 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
355 0, // uint32_t queueFamilyIndexCount
356 DE_NULL, // const uint32_t* pQueueFamilyIndices
357 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
358 };
359
360 m_dummyImage = de::MovePtr<vk::ImageWithMemory>(
361 new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
362 m_dummyImageView =
363 vk::makeImageView(vk, device, **m_dummyImage, vk::VK_IMAGE_VIEW_TYPE_2D, format, colorSubresourceRange);
364 }
365
createDummyRenderPass(void)366 void ShaderObjectRenderingInstance::createDummyRenderPass(void)
367 {
368 const vk::DeviceInterface &vk = m_context.getDeviceInterface();
369 const vk::VkDevice device = m_context.getDevice();
370 vk::VkFormat format = m_params.colorFormat == vk::VK_FORMAT_R8G8B8A8_UNORM ? vk::VK_FORMAT_R32G32B32A32_SFLOAT :
371 vk::VK_FORMAT_R8G8B8A8_UNORM;
372 m_dummyRenderPass = vk::makeRenderPass(vk, device, format);
373 m_dummyFramebuffer = vk::makeFramebuffer(vk, device, *m_dummyRenderPass, 1u, &*m_dummyImageView,
374 m_renderArea.extent.width, m_renderArea.extent.height);
375 }
376
getClearValue(const tcu::TextureFormat tcuFormat)377 vk::VkClearValue getClearValue(const tcu::TextureFormat tcuFormat)
378 {
379 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(tcuFormat.type);
380
381 if (channelClass != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER &&
382 channelClass != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
383 return vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 1.0f});
384
385 const tcu::IVec4 bits = tcu::min(tcu::getTextureFormatBitDepth(tcuFormat), tcu::IVec4(32));
386 const int signBit = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0);
387
388 if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
389 return vk::makeClearValueColorU32(0u, 0u, 0u, uint32_t((uint64_t(1) << (bits[3] - signBit)) - 1));
390
391 return vk::makeClearValueColorI32(0u, 0u, 0u, int32_t((uint64_t(1) << (bits[3] - signBit)) - 1));
392 }
393
beginRendering(vk::VkCommandBuffer cmdBuffer)394 void ShaderObjectRenderingInstance::beginRendering(vk::VkCommandBuffer cmdBuffer)
395 {
396 const vk::DeviceInterface &vk = m_context.getDeviceInterface();
397 const vk::VkClearValue floatClearValue = vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 1.0f});
398 const vk::VkClearValue clearDepthValue = vk::makeClearValueDepthStencil(1.0f, 0u);
399
400 vk::VkRenderingAttachmentInfo colorAttachment{
401 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
402 DE_NULL, // const void* pNext;
403 VK_NULL_HANDLE, // VkImageView imageView;
404 vk::VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
405 vk::VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
406 DE_NULL, // VkImageView resolveImageView;
407 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
408 vk::VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
409 vk::VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
410 floatClearValue // VkClearValue clearValue;
411 };
412
413 uint32_t outputCount =
414 m_params.colorAttachmentCount + m_params.extraFragmentOutputCount + m_params.extraAttachmentCount;
415 std::vector<vk::VkRenderingAttachmentInfo> colorAttachments(outputCount);
416 uint32_t i = 0;
417 if (m_params.extraOutputs == BEFORE ||
418 (m_params.extraOutputs == BETWEEN && m_params.colorAttachmentCount + m_params.extraAttachmentCount == 0))
419 {
420 colorAttachment.imageView = VK_NULL_HANDLE;
421 for (uint32_t j = 0; j < m_params.extraFragmentOutputCount; ++j)
422 colorAttachments[i++] = colorAttachment;
423 }
424 for (uint32_t j = 0; j < m_params.colorAttachmentCount + m_params.extraAttachmentCount; ++j)
425 {
426 if (m_params.extraOutputs == BETWEEN &&
427 i == (m_params.colorAttachmentCount + m_params.extraAttachmentCount) / 2 + 1)
428 {
429 colorAttachment.imageView = VK_NULL_HANDLE;
430 for (uint32_t k = 0; k < m_params.extraFragmentOutputCount; ++k)
431 colorAttachments[i++] = colorAttachment;
432 }
433 colorAttachment.imageView = *m_colorImageViews[j];
434 colorAttachment.clearValue = getClearValue(vk::mapVkFormat(m_colorFormats[j]));
435
436 colorAttachments[i++] = colorAttachment;
437 }
438 if (m_params.extraOutputs == AFTER ||
439 (m_params.extraOutputs == BETWEEN && m_params.colorAttachmentCount + m_params.extraAttachmentCount == 1))
440 {
441 colorAttachment.imageView = VK_NULL_HANDLE;
442 for (uint32_t j = 0; j < m_params.extraFragmentOutputCount; ++j)
443 colorAttachments[i++] = colorAttachment;
444 }
445
446 vk::VkRenderingAttachmentInfo depthAttachment{
447 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
448 DE_NULL, // const void* pNext;
449 *m_depthImageView, // VkImageView imageView;
450 vk::VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
451 vk::VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
452 DE_NULL, // VkImageView resolveImageView;
453 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
454 vk::VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
455 vk::VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
456 clearDepthValue // VkClearValue clearValue;
457 };
458
459 vk::VkRenderingInfoKHR renderingInfo{
460 vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
461 DE_NULL,
462 (vk::VkRenderingFlags)0u, // VkRenderingFlagsKHR flags;
463 m_renderArea, // VkRect2D renderArea;
464 1u, // uint32_t layerCount;
465 0x0, // uint32_t viewMask;
466 (uint32_t)colorAttachments.size(), // uint32_t colorAttachmentCount;
467 colorAttachments.data(), // const VkRenderingAttachmentInfoKHR* pColorAttachments;
468 m_params.useDepthAttachment ? &depthAttachment :
469 DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
470 DE_NULL, // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
471 };
472
473 vk.cmdBeginRendering(cmdBuffer, &renderingInfo);
474 }
475
setColorFormats(const vk::InstanceDriver & vki)476 void ShaderObjectRenderingInstance::setColorFormats(const vk::InstanceDriver &vki)
477 {
478 const auto physicalDevice = m_context.getPhysicalDevice();
479
480 m_colorFormats.resize(m_params.colorAttachmentCount + m_params.extraAttachmentCount);
481 if (m_params.randomColorFormats)
482 {
483 if (m_colorFormats.size() > 0)
484 {
485 m_colorFormats[0] = m_params.colorFormat;
486 }
487 de::Random random(102030);
488 for (uint32_t i = 1; i < (uint32_t)m_colorFormats.size(); ++i)
489 {
490 if (i <= m_params.extraAttachmentCount && m_params.extraAttachments == BEFORE)
491 m_colorFormats[i] = m_params.colorFormat;
492 else
493 {
494 while (true)
495 {
496 // Find random color format, and make sure it is supported
497 vk::VkFormat format =
498 randomColorFormats[random.getUint32() % DE_LENGTH_OF_ARRAY(randomColorFormats)];
499 vk::VkImageFormatProperties colorImageFormatProperties;
500 const auto colorResult = vki.getPhysicalDeviceImageFormatProperties(
501 physicalDevice, format, vk::VK_IMAGE_TYPE_2D, vk::VK_IMAGE_TILING_OPTIMAL,
502 (vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT), 0,
503 &colorImageFormatProperties);
504 if (colorResult == vk::VK_SUCCESS)
505 {
506 m_colorFormats[i] = format;
507 break;
508 }
509 }
510 }
511 }
512 }
513 else
514 {
515 for (auto &colorFormat : m_colorFormats)
516 colorFormat = m_params.colorFormat;
517 }
518 }
519
generateExpectedImage(const tcu::PixelBufferAccess & outputImage,const uint32_t width,const uint32_t height,uint32_t attachmentIndex)520 void ShaderObjectRenderingInstance::generateExpectedImage(const tcu::PixelBufferAccess &outputImage,
521 const uint32_t width, const uint32_t height,
522 uint32_t attachmentIndex)
523 {
524 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(outputImage.getFormat().type);
525 const vk::VkClearValue clearValue = getClearValue(outputImage.getFormat());
526
527 const uint32_t xOffset = 8;
528 const uint32_t yOffset = 8;
529
530 if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
531 tcu::clear(outputImage, tcu::UVec4(clearValue.color.uint32));
532 else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
533 tcu::clear(outputImage, tcu::IVec4(clearValue.color.int32));
534 else
535 tcu::clear(outputImage, tcu::Vec4(clearValue.color.float32));
536
537 if ((m_params.extraAttachments == BEFORE && attachmentIndex < m_params.extraAttachmentCount) ||
538 (m_params.extraAttachments == BETWEEN && attachmentIndex > m_params.colorAttachmentCount / 2u &&
539 attachmentIndex <= m_params.colorAttachmentCount / 2u + m_params.extraAttachmentCount) ||
540 (m_params.extraAttachments == AFTER && attachmentIndex >= m_params.colorAttachmentCount))
541 return;
542
543 tcu::Vec4 setColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
544 tcu::IVec4 setColorInt = tcu::IVec4(0, 0, 0, 0);
545 tcu::UVec4 setColorUint = tcu::UVec4(0u, 0u, 0u, 0u);
546
547 for (int32_t i = 0; i < tcu::getNumUsedChannels(outputImage.getFormat().order); ++i)
548 {
549 setColor[i] = 1.0f;
550 setColorInt[i] = 255;
551 setColorUint[i] = 255u;
552 }
553
554 for (uint32_t j = 0; j < height; ++j)
555 {
556 for (uint32_t i = 0; i < width; ++i)
557 {
558 if (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset)
559 {
560 if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
561 outputImage.setPixel(setColorUint, i, j, 0);
562 else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
563 outputImage.setPixel(setColorInt, i, j, 0);
564 else
565 outputImage.setPixel(setColor, i, j, 0);
566 }
567 }
568 }
569 }
570
iterate(void)571 tcu::TestStatus ShaderObjectRenderingInstance::iterate(void)
572 {
573 const vk::VkInstance instance = m_context.getInstance();
574 const vk::InstanceDriver instanceDriver(m_context.getPlatformInterface(), instance);
575 const vk::DeviceInterface &vk = m_context.getDeviceInterface();
576 const vk::VkDevice device = m_context.getDevice();
577 const vk::VkQueue queue = m_context.getUniversalQueue();
578 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
579 auto &alloc = m_context.getDefaultAllocator();
580 tcu::TestLog &log = m_context.getTestContext().getLog();
581 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(
582 m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
583 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
584 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
585 const bool taskSupported = m_context.getMeshShaderFeaturesEXT().taskShader;
586 const bool meshSupported = m_context.getMeshShaderFeaturesEXT().meshShader;
587
588 const auto colorSubresourceRange = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
589 auto depthSubresourceRange = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u);
590 if (m_params.useDepthAttachment && tcu::hasStencilComponent(mapVkFormat(m_params.depthFormat).order))
591 depthSubresourceRange.aspectMask |= vk::VK_IMAGE_ASPECT_STENCIL_BIT;
592 const auto colorSubresourceLayers = vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
593 vk::VkExtent3D extent = {m_renderArea.extent.width, m_renderArea.extent.height, 1};
594
595 setColorFormats(instanceDriver);
596
597 vk::VkImageCreateInfo createInfo = {
598 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
599 DE_NULL, // const void* pNext
600 0u, // VkImageCreateFlags flags
601 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
602 vk::VK_FORMAT_UNDEFINED, // VkFormat format
603 {32, 32, 1}, // VkExtent3D extent
604 1u, // uint32_t mipLevels
605 1u, // uint32_t arrayLayers
606 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
607 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
608 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
609 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
610 0, // uint32_t queueFamilyIndexCount
611 DE_NULL, // const uint32_t* pQueueFamilyIndices
612 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
613 };
614
615 const vk::VkImageCreateInfo depthCreateInfo = {
616 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
617 DE_NULL, // const void* pNext
618 0u, // VkImageCreateFlags flags
619 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
620 m_params.depthFormat, // VkFormat format
621 {32, 32, 1}, // VkExtent3D extent
622 1u, // uint32_t mipLevels
623 1u, // uint32_t arrayLayers
624 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
625 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
626 vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
627 vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
628 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
629 0, // uint32_t queueFamilyIndexCount
630 DE_NULL, // const uint32_t* pQueueFamilyIndices
631 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
632 };
633
634 uint32_t colorAttachmentCount = m_params.colorAttachmentCount + m_params.extraAttachmentCount;
635 std::vector<de::MovePtr<vk::ImageWithMemory>> colorImages(colorAttachmentCount);
636 m_colorImageViews.resize(colorAttachmentCount);
637 for (uint32_t i = 0; i < colorAttachmentCount; ++i)
638 {
639 createInfo.format = m_colorFormats[i];
640 colorImages[i] = de::MovePtr<vk::ImageWithMemory>(
641 new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
642 m_colorImageViews[i] = vk::makeImageView(vk, device, **colorImages[i], vk::VK_IMAGE_VIEW_TYPE_2D,
643 createInfo.format, colorSubresourceRange);
644 }
645
646 de::MovePtr<vk::ImageWithMemory> depthImage;
647 if (m_params.useDepthAttachment)
648 {
649 depthImage = de::MovePtr<vk::ImageWithMemory>(
650 new vk::ImageWithMemory(vk, device, alloc, depthCreateInfo, vk::MemoryRequirement::Any));
651 m_depthImageView = vk::makeImageView(vk, device, **depthImage, vk::VK_IMAGE_VIEW_TYPE_2D, m_params.depthFormat,
652 depthSubresourceRange);
653 }
654
655 std::vector<de::MovePtr<vk::BufferWithMemory>> colorOutputBuffers;
656 for (uint32_t i = 0; i < colorAttachmentCount; ++i)
657 {
658 const vk::VkDeviceSize colorOutputBufferSize = m_renderArea.extent.width * m_renderArea.extent.height *
659 tcu::getPixelSize(vk::mapVkFormat(m_colorFormats[i]));
660 colorOutputBuffers.push_back(de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
661 vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT),
662 vk::MemoryRequirement::HostVisible)));
663 }
664
665 const auto &binaries = m_context.getBinaryCollection();
666 const auto vertShader =
667 vk::createShader(vk, device,
668 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("vertDepth"),
669 tessellationSupported, geometrySupported));
670 const auto fragShader =
671 vk::createShader(vk, device,
672 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("fragMulti"),
673 tessellationSupported, geometrySupported));
674
675 const vk::Move<vk::VkCommandPool> cmdPool(vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
676 const vk::Move<vk::VkCommandBuffer> cmdBuffer(
677 vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
678
679 vk::beginCommandBuffer(vk, *cmdBuffer);
680
681 if (m_params.dummyRenderPass == DUMMY_DYNAMIC)
682 {
683 createDummyImage();
684 const vk::VkClearValue clearValue = vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 1.0f});
685 vk::beginRendering(vk, *cmdBuffer, *m_dummyImageView, m_renderArea, clearValue);
686 }
687 else if (m_params.dummyRenderPass == DUMMY_STATIC)
688 {
689 createDummyImage();
690 createDummyRenderPass();
691 const vk::VkClearValue clearValue = vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 1.0f});
692 vk::beginRenderPass(vk, *cmdBuffer, *m_dummyRenderPass, *m_dummyFramebuffer, m_renderArea, clearValue);
693 }
694
695 if (m_params.bindShadersBeforeBeginRendering)
696 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE,
697 *fragShader, taskSupported, meshSupported);
698
699 if (m_params.dummyRenderPass == DUMMY_DYNAMIC)
700 {
701 vk::endRendering(vk, *cmdBuffer);
702 }
703 else if (m_params.dummyRenderPass == DUMMY_STATIC)
704 {
705 vk::endRenderPass(vk, *cmdBuffer);
706 }
707
708 for (const auto &colorImage : colorImages)
709 {
710 vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(
711 vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
712 vk::VK_IMAGE_LAYOUT_GENERAL, **colorImage, colorSubresourceRange);
713 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
714 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u,
715 (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
716 &preImageBarrier);
717 }
718
719 if (m_params.useDepthAttachment)
720 {
721 vk::VkImageMemoryBarrier preDepthImageBarrier = vk::makeImageMemoryBarrier(
722 vk::VK_ACCESS_NONE, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
723 vk::VK_IMAGE_LAYOUT_GENERAL, **depthImage, depthSubresourceRange);
724 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
725 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, (vk::VkDependencyFlags)0u, 0u,
726 (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
727 &preDepthImageBarrier);
728 }
729
730 beginRendering(*cmdBuffer);
731 vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
732 vk::VkBool32 colorBlendEnable = VK_FALSE;
733 vk::VkColorBlendEquationEXT colorBlendEquation = {
734 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
735 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor;
736 vk::VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
737 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
738 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor;
739 vk::VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
740 };
741 vk::VkColorComponentFlags colorWriteMask = vk::VK_COLOR_COMPONENT_R_BIT | vk::VK_COLOR_COMPONENT_G_BIT |
742 vk::VK_COLOR_COMPONENT_B_BIT | vk::VK_COLOR_COMPONENT_A_BIT;
743 uint32_t count = colorAttachmentCount + m_params.extraFragmentOutputCount;
744 if (count == 0)
745 ++count;
746 std::vector<vk::VkBool32> colorBlendEnables(count, colorBlendEnable);
747 std::vector<vk::VkColorBlendEquationEXT> colorBlendEquations(count, colorBlendEquation);
748 std::vector<vk::VkColorComponentFlags> colorWriteMasks(count, colorWriteMask);
749 vk.cmdSetColorBlendEnableEXT(*cmdBuffer, 0u, count, colorBlendEnables.data());
750 vk.cmdSetColorBlendEquationEXT(*cmdBuffer, 0u, count, colorBlendEquations.data());
751 vk.cmdSetColorWriteMaskEXT(*cmdBuffer, 0u, count, colorWriteMasks.data());
752 std::vector<vk::VkBool32> colorWriteEnables(count, VK_TRUE);
753 vk.cmdSetColorWriteEnableEXT(*cmdBuffer, count, colorWriteEnables.data());
754 vk.cmdSetDepthWriteEnable(*cmdBuffer, VK_TRUE);
755 vk.cmdSetDepthTestEnable(*cmdBuffer, VK_TRUE);
756 vk.cmdSetDepthCompareOp(*cmdBuffer, vk::VK_COMPARE_OP_LESS);
757 vk::bindNullTaskMeshShaders(vk, *cmdBuffer, m_context.getMeshShaderFeaturesEXT());
758 if (!m_params.bindShadersBeforeBeginRendering)
759 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE,
760 *fragShader, taskSupported, meshSupported);
761 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
762 vk::endRendering(vk, *cmdBuffer);
763
764 for (const auto &colorImage : colorImages)
765 {
766 vk::VkImageMemoryBarrier postImageBarrier = vk::makeImageMemoryBarrier(
767 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL,
768 vk::VK_IMAGE_LAYOUT_GENERAL, **colorImage, colorSubresourceRange);
769 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
770 vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u,
771 (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
772 &postImageBarrier);
773 }
774
775 if (m_params.useDepthAttachment)
776 {
777 vk::VkImageMemoryBarrier postDepthImageBarrier = vk::makeImageMemoryBarrier(
778 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT,
779 vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **depthImage, depthSubresourceRange);
780 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
781 vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u,
782 (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
783 &postDepthImageBarrier);
784 }
785
786 const vk::VkBufferImageCopy colorCopyRegion = vk::makeBufferImageCopy(extent, colorSubresourceLayers);
787 for (uint32_t i = 0; i < colorAttachmentCount; ++i)
788 vk.cmdCopyImageToBuffer(*cmdBuffer, **colorImages[i], vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffers[i], 1u,
789 &colorCopyRegion);
790
791 vk::endCommandBuffer(vk, *cmdBuffer);
792
793 vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
794
795 std::vector<tcu::ConstPixelBufferAccess> colorResultBuffers;
796 for (uint32_t i = 0; i < colorAttachmentCount; ++i)
797 colorResultBuffers.push_back(tcu::ConstPixelBufferAccess(
798 vk::mapVkFormat(m_colorFormats[i]), m_renderArea.extent.width, m_renderArea.extent.height, 1,
799 (const void *)colorOutputBuffers[i]->getAllocation().getHostPtr()));
800
801 const uint32_t width = m_renderArea.extent.width;
802 const uint32_t height = m_renderArea.extent.height;
803 const uint32_t xOffset = 8;
804 const uint32_t yOffset = 8;
805
806 for (uint32_t k = 0; k < (uint32_t)colorImages.size(); ++k)
807 {
808 tcu::TextureLevel textureLevel(mapVkFormat(m_colorFormats[k]), width, height);
809 const tcu::PixelBufferAccess expectedImage = textureLevel.getAccess();
810 generateExpectedImage(expectedImage, width, height, k);
811
812 if (vk::isFloatFormat(m_colorFormats[k]))
813 {
814 if (!tcu::floatThresholdCompare(log, "Image Comparison", "", expectedImage, colorResultBuffers[k],
815 tcu::Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
816 return tcu::TestStatus::fail("Fail");
817 }
818 else
819 {
820 if (!tcu::intThresholdCompare(log, "Image Comparison", "", expectedImage, colorResultBuffers[k],
821 tcu::UVec4(2), tcu::COMPARE_LOG_RESULT))
822 return tcu::TestStatus::fail("Fail");
823 }
824 }
825
826 if (m_params.useDepthAttachment)
827 {
828 const auto depthBuffer = readDepthAttachment(
829 vk, device, queue, queueFamilyIndex, alloc, **depthImage, m_params.depthFormat,
830 tcu::UVec2(m_renderArea.extent.width, m_renderArea.extent.height), vk::VK_IMAGE_LAYOUT_GENERAL);
831 const auto depthAccess = depthBuffer->getAccess();
832
833 const float depthEpsilon = 0.02f;
834 for (uint32_t j = 0; j < height; ++j)
835 {
836 for (uint32_t i = 0; i < width; ++i)
837 {
838 const float depth = depthAccess.getPixDepth(i, j);
839 if (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset)
840 {
841 if (deFloatAbs(depth - 0.5f) > depthEpsilon)
842 {
843 log << tcu::TestLog::Message << "Depth at (" << i << ", " << j
844 << ") is expected to be 0.5, but was (" << depth << ")" << tcu::TestLog::EndMessage;
845 return tcu::TestStatus::fail("Fail");
846 }
847 }
848 else
849 {
850 if (deFloatAbs(depth - 1.0f) > depthEpsilon)
851 {
852 log << tcu::TestLog::Message << "Color at (" << i << ", " << j
853 << ") is expected to be 0.0, but was (" << depth << ")" << tcu::TestLog::EndMessage;
854 return tcu::TestStatus::fail("Fail");
855 }
856 }
857 }
858 }
859 }
860
861 return tcu::TestStatus::pass("Pass");
862 }
863
864 class ShaderObjectRenderingCase : public vkt::TestCase
865 {
866 public:
ShaderObjectRenderingCase(tcu::TestContext & testCtx,const std::string & name,const TestParams & params)867 ShaderObjectRenderingCase(tcu::TestContext &testCtx, const std::string &name, const TestParams ¶ms)
868 : vkt::TestCase(testCtx, name)
869 , m_params(params)
870 {
871 }
~ShaderObjectRenderingCase(void)872 virtual ~ShaderObjectRenderingCase(void)
873 {
874 }
875
876 void checkSupport(vkt::Context &context) const override;
877 virtual void initPrograms(vk::SourceCollections &programCollection) const override;
createInstance(Context & context) const878 TestInstance *createInstance(Context &context) const override
879 {
880 return new ShaderObjectRenderingInstance(context, m_params);
881 }
882
883 private:
884 TestParams m_params;
885 };
886
checkSupport(Context & context) const887 void ShaderObjectRenderingCase::checkSupport(Context &context) const
888 {
889 const auto &vki = context.getInstanceInterface();
890 const auto physicalDevice = context.getPhysicalDevice();
891 const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(vki, physicalDevice);
892
893 context.requireDeviceFunctionality("VK_EXT_shader_object");
894
895 if (m_params.colorAttachmentCount + m_params.extraAttachmentCount + m_params.extraFragmentOutputCount >
896 properties.limits.maxColorAttachments)
897 TCU_THROW(NotSupportedError,
898 "Tests uses more color attachments than VkPhysicalDeviceLimits::maxColorAttachments");
899
900 vk::VkImageFormatProperties colorImageFormatProperties;
901 const auto colorResult = vki.getPhysicalDeviceImageFormatProperties(
902 physicalDevice, m_params.colorFormat, vk::VK_IMAGE_TYPE_2D, vk::VK_IMAGE_TILING_OPTIMAL,
903 (vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT), 0,
904 &colorImageFormatProperties);
905 if (colorResult != vk::VK_SUCCESS)
906 TCU_THROW(NotSupportedError, "Format unsupported for tiling");
907 vk::VkImageFormatProperties depthImageFormatProperties;
908 if (m_params.useDepthAttachment)
909 {
910 const auto depthResult = vki.getPhysicalDeviceImageFormatProperties(
911 physicalDevice, m_params.depthFormat, vk::VK_IMAGE_TYPE_2D, vk::VK_IMAGE_TILING_OPTIMAL,
912 (vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT), 0,
913 &depthImageFormatProperties);
914 if (depthResult != vk::VK_SUCCESS)
915 TCU_THROW(NotSupportedError, "Format unsupported for tiling");
916 }
917 }
918
initPrograms(vk::SourceCollections & programCollection) const919 void ShaderObjectRenderingCase::initPrograms(vk::SourceCollections &programCollection) const
920 {
921 std::stringstream vertDepth;
922 std::stringstream fragMulti;
923
924 vertDepth << "#version 450\n"
925 << "void main() {\n"
926 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
927 << " gl_Position = vec4(pos - 0.5f, 0.5f, 1.0f);\n"
928 << "}\n";
929
930 fragMulti << "#version 450\n";
931 uint32_t outputCount = m_params.colorAttachmentCount + m_params.extraFragmentOutputCount;
932 for (uint32_t i = 0; i < outputCount; ++i)
933 {
934 uint32_t j = i;
935 if (m_params.extraAttachments == BEFORE || (m_params.extraAttachments == BETWEEN && i > outputCount / 2))
936 j += m_params.extraAttachmentCount;
937 bool firstWrittenAttachment =
938 (m_params.extraOutputs == BEFORE) ? (i == m_params.extraFragmentOutputCount) : (i == 0);
939 if (vk::isUintFormat(m_params.colorFormat) && (firstWrittenAttachment || !m_params.randomColorFormats))
940 fragMulti << "layout (location = " << j << ") out uvec4 outColor" << j << ";\n";
941 else if (vk::isIntFormat(m_params.colorFormat) && (firstWrittenAttachment || !m_params.randomColorFormats))
942 fragMulti << "layout (location = " << j << ") out ivec4 outColor" << j << ";\n";
943 else
944 fragMulti << "layout (location = " << j << ") out vec4 outColor" << j << ";\n";
945 }
946 fragMulti << "void main() {\n";
947 for (uint32_t i = 0; i < outputCount; ++i)
948 {
949 uint32_t j = i;
950 if (m_params.extraAttachments == BEFORE || (m_params.extraAttachments == BETWEEN && i > outputCount / 2))
951 j += m_params.extraAttachmentCount;
952 bool firstWrittenAttachment =
953 (m_params.extraOutputs == BEFORE) ? (i == m_params.extraFragmentOutputCount) : (i == 0);
954 if (vk::isUintFormat(m_params.colorFormat) && (firstWrittenAttachment || !m_params.randomColorFormats))
955 fragMulti << " outColor" << j << " = uvec4(255);\n";
956 else if (vk::isIntFormat(m_params.colorFormat) && (firstWrittenAttachment || !m_params.randomColorFormats))
957 fragMulti << " outColor" << j << " = ivec4(255);\n";
958 else
959 fragMulti << " outColor" << j << " = vec4(1.0f);\n";
960 }
961 if (m_params.writeGlFragDepth)
962 fragMulti << " gl_FragDepth = 0.5f;\n";
963 fragMulti << "}\n";
964
965 programCollection.glslSources.add("vertDepth") << glu::VertexSource(vertDepth.str());
966 programCollection.glslSources.add("fragMulti") << glu::FragmentSource(fragMulti.str());
967 }
968
969 } // namespace
970
getFormatCaseName(vk::VkFormat format)971 std::string getFormatCaseName(vk::VkFormat format)
972 {
973 return de::toLower(de::toString(getFormatStr(format)).substr(10));
974 }
975
createShaderObjectRenderingTests(tcu::TestContext & testCtx)976 tcu::TestCaseGroup *createShaderObjectRenderingTests(tcu::TestContext &testCtx)
977 {
978 de::MovePtr<tcu::TestCaseGroup> renderingGroup(new tcu::TestCaseGroup(testCtx, "rendering"));
979
980 const struct
981 {
982 uint32_t colorAttachmentCount;
983 const char *name;
984 } colorAttachmentCountTests[] = {
985 {
986 0u,
987 "color_attachment_count_0",
988 },
989 {
990 1u,
991 "color_attachment_count_1",
992 },
993 {
994 4u,
995 "color_attachment_count_4",
996 },
997 {
998 8u,
999 "color_attachment_count_8",
1000 },
1001 };
1002
1003 const struct
1004 {
1005 uint32_t extraAttachmentCount;
1006 ExtraAttachments extraAttachment;
1007 const char *name;
1008 } extraAttachmentTests[] = {
1009 {
1010 0u,
1011 NONE,
1012 "none",
1013 },
1014 {
1015 1u,
1016 BEFORE,
1017 "extra_attachment_before_1",
1018 },
1019 {
1020 1u,
1021 BETWEEN,
1022 "extra_attachment_between_1",
1023 },
1024 {
1025 1u,
1026 AFTER,
1027 "extra_attachment_after_1",
1028 },
1029 {
1030 2u,
1031 BEFORE,
1032 "extra_attachment_before_2",
1033 },
1034 {
1035 2u,
1036 BETWEEN,
1037 "extra_attachment_between_2",
1038 },
1039 {
1040 2u,
1041 AFTER,
1042 "extra_attachment_after_2",
1043 },
1044 };
1045
1046 const struct
1047 {
1048 uint32_t extraFragmentOutputCount;
1049 ExtraAttachments extraAttachment;
1050 const char *name;
1051 } extraOutputTests[] = {
1052 {
1053 0u,
1054 NONE,
1055 "none",
1056 },
1057 {
1058 1u,
1059 BEFORE,
1060 "extra_output_before_1",
1061 },
1062 {
1063 1u,
1064 BETWEEN,
1065 "extra_output_between_1",
1066 },
1067 {
1068 1u,
1069 AFTER,
1070 "extra_output_after_1",
1071 },
1072 {
1073 2u,
1074 BEFORE,
1075 "extra_output_before_2",
1076 },
1077 {
1078 2u,
1079 BETWEEN,
1080 "extra_output_between_2",
1081 },
1082 {
1083 2u,
1084 AFTER,
1085 "extra_output_after_2",
1086 },
1087 };
1088
1089 const vk::VkFormat depthStencilFormats[] = {
1090 vk::VK_FORMAT_D16_UNORM, vk::VK_FORMAT_X8_D24_UNORM_PACK32, vk::VK_FORMAT_D32_SFLOAT,
1091 vk::VK_FORMAT_D16_UNORM_S8_UINT, vk::VK_FORMAT_D24_UNORM_S8_UINT, vk::VK_FORMAT_D32_SFLOAT_S8_UINT,
1092 };
1093
1094 const struct
1095 {
1096 DummyRenderPass dummyRenderPass;
1097 const char *name;
1098 } dummyRenderPassTests[] = {
1099 {
1100 DUMMY_NONE,
1101 "none",
1102 },
1103 {
1104 DUMMY_DYNAMIC,
1105 "dynamic",
1106 },
1107 {
1108 DUMMY_STATIC,
1109 "static",
1110 },
1111 };
1112
1113 for (const auto &colorAttachmentCountTest : colorAttachmentCountTests)
1114 {
1115 de::MovePtr<tcu::TestCaseGroup> colorAttachmentGroup(
1116 new tcu::TestCaseGroup(testCtx, colorAttachmentCountTest.name));
1117 for (const auto &extraAttachment : extraAttachmentTests)
1118 {
1119 de::MovePtr<tcu::TestCaseGroup> extraAttachmentGroup(new tcu::TestCaseGroup(testCtx, extraAttachment.name));
1120 for (const auto &extraOutput : extraOutputTests)
1121 {
1122 if (extraAttachment.extraAttachment != NONE && extraOutput.extraFragmentOutputCount != NONE)
1123 continue;
1124
1125 de::MovePtr<tcu::TestCaseGroup> extraOutputGroup(new tcu::TestCaseGroup(testCtx, extraOutput.name));
1126
1127 for (const auto &dummyRenderPass : dummyRenderPassTests)
1128 {
1129 de::MovePtr<tcu::TestCaseGroup> dummyRenderPassGroup(
1130 new tcu::TestCaseGroup(testCtx, dummyRenderPass.name));
1131 for (uint32_t m = 0; m < 2; ++m)
1132 {
1133 bool useRandomColorFormats = m == 0;
1134 if (useRandomColorFormats && colorAttachmentCountTest.colorAttachmentCount < 2)
1135 continue;
1136 std::string randomColorFormatsName =
1137 useRandomColorFormats ? "random_color_formats" : "same_color_formats";
1138 de::MovePtr<tcu::TestCaseGroup> randomColorFormatsGroup(
1139 new tcu::TestCaseGroup(testCtx, randomColorFormatsName.c_str()));
1140 for (uint32_t k = 0; k < 2; ++k)
1141 {
1142 bool bindShadersBeforeBeginRendering = k == 0;
1143 std::string bindName = bindShadersBeforeBeginRendering ? "before" : "after";
1144 de::MovePtr<tcu::TestCaseGroup> bindGroup(
1145 new tcu::TestCaseGroup(testCtx, bindName.c_str()));
1146 for (uint32_t l = 0; l < 2; ++l)
1147 {
1148 bool writeGlFragDepth = l == 0;
1149 std::string writeGlFragName = writeGlFragDepth ? "gl_frag_write" : "none";
1150 de::MovePtr<tcu::TestCaseGroup> fragWriteGroup(
1151 new tcu::TestCaseGroup(testCtx, writeGlFragName.c_str()));
1152 for (uint32_t i = 0; i < DE_LENGTH_OF_ARRAY(colorFormats); ++i)
1153 {
1154 if (extraAttachment.extraAttachmentCount >
1155 colorAttachmentCountTest.colorAttachmentCount)
1156 continue;
1157
1158 if (!bindShadersBeforeBeginRendering &&
1159 dummyRenderPass.dummyRenderPass != DUMMY_NONE)
1160 continue;
1161
1162 const auto colorFormat = colorFormats[i];
1163
1164 TestParams params;
1165 params.colorAttachmentCount = colorAttachmentCountTest.colorAttachmentCount;
1166 params.extraAttachmentCount = extraAttachment.extraAttachmentCount;
1167 params.extraAttachments = extraAttachment.extraAttachment;
1168 params.extraFragmentOutputCount = extraOutput.extraFragmentOutputCount;
1169 params.extraOutputs = extraOutput.extraAttachment;
1170 params.useDepthAttachment = false;
1171 params.colorFormat = colorFormat;
1172 params.depthFormat = vk::VK_FORMAT_UNDEFINED;
1173 params.bindShadersBeforeBeginRendering = bindShadersBeforeBeginRendering;
1174 params.dummyRenderPass = dummyRenderPass.dummyRenderPass;
1175 params.writeGlFragDepth = writeGlFragDepth;
1176 params.randomColorFormats = useRandomColorFormats;
1177
1178 std::string name = getFormatCaseName(colorFormat);
1179 fragWriteGroup->addChild(new ShaderObjectRenderingCase(testCtx, name, params));
1180
1181 if (writeGlFragDepth)
1182 continue;
1183
1184 for (uint32_t j = 0; j < DE_LENGTH_OF_ARRAY(depthStencilFormats); ++j)
1185 {
1186 const auto depthFormat = depthStencilFormats[j];
1187 params.useDepthAttachment = true;
1188 params.depthFormat = depthFormat;
1189
1190 std::string depthTestName = name + "_" + getFormatCaseName(depthFormat);
1191 fragWriteGroup->addChild(
1192 new ShaderObjectRenderingCase(testCtx, depthTestName, params));
1193 }
1194 }
1195 bindGroup->addChild(fragWriteGroup.release());
1196 }
1197 randomColorFormatsGroup->addChild(bindGroup.release());
1198 }
1199 dummyRenderPassGroup->addChild(randomColorFormatsGroup.release());
1200 }
1201 extraOutputGroup->addChild(dummyRenderPassGroup.release());
1202 }
1203 extraAttachmentGroup->addChild(extraOutputGroup.release());
1204 }
1205 colorAttachmentGroup->addChild(extraAttachmentGroup.release());
1206 }
1207 renderingGroup->addChild(colorAttachmentGroup.release());
1208 }
1209
1210 return renderingGroup.release();
1211 }
1212
1213 } // namespace ShaderObject
1214 } // namespace vkt
1215