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