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 Misc Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktShaderObjectMiscTests.hpp"
26 #include "deUniquePtr.hpp"
27 #include "tcuTestCase.hpp"
28 #include "vktTestCase.hpp"
29 #include "vkShaderObjectUtil.hpp"
30 #include "vktShaderObjectCreateUtil.hpp"
31 #include "vkBufferWithMemory.hpp"
32 #include "vkImageWithMemory.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkObjUtil.hpp"
36 #include "vkImageUtil.hpp"
37 #include "vkCmdUtil.hpp"
38 #include "vkBarrierUtil.hpp"
39 #include "deMath.hpp"
40 #include "vktCustomInstancesDevices.hpp"
41 #include "tcuCommandLine.hpp"
42 #include "tcuTextureUtil.hpp"
43
44 namespace vkt
45 {
46 namespace ShaderObject
47 {
48
49 namespace
50 {
51
52 struct TestParams
53 {
54 bool blendEnabled[2];
55 bool vertexInputBefore;
56 bool vertexBuffersNullStride;
57 uint32_t stride;
58 bool destroyDescriptorSetLayout;
59 };
60
findDSFormat(const vk::InstanceInterface & vki,const vk::VkPhysicalDevice physicalDevice)61 vk::VkFormat findDSFormat(const vk::InstanceInterface &vki, const vk::VkPhysicalDevice physicalDevice)
62 {
63 const vk::VkFormat dsFormats[] = {
64 vk::VK_FORMAT_D24_UNORM_S8_UINT,
65 vk::VK_FORMAT_D32_SFLOAT_S8_UINT,
66 vk::VK_FORMAT_D16_UNORM_S8_UINT,
67 };
68
69 for (uint32_t i = 0; i < 3; ++i)
70 {
71 const vk::VkFormatProperties formatProperties =
72 getPhysicalDeviceFormatProperties(vki, physicalDevice, dsFormats[i]);
73 if ((formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
74 return dsFormats[i];
75 }
76 return vk::VK_FORMAT_UNDEFINED;
77 }
78
79 class ShaderObjectMiscInstance : public vkt::TestInstance
80 {
81 public:
ShaderObjectMiscInstance(Context & context,const TestParams & params)82 ShaderObjectMiscInstance(Context &context, const TestParams ¶ms) : vkt::TestInstance(context), m_params(params)
83 {
84 }
~ShaderObjectMiscInstance(void)85 virtual ~ShaderObjectMiscInstance(void)
86 {
87 }
88
89 tcu::TestStatus iterate(void) override;
90
91 private:
92 void setVertexInput(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkDeviceSize stride) const;
93 void bindVertexBuffers(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkDeviceSize *stride,
94 vk::VkBuffer buffer, vk::VkDeviceSize bufferSize) const;
95 TestParams m_params;
96 };
97
setVertexInput(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkDeviceSize stride) const98 void ShaderObjectMiscInstance::setVertexInput(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer,
99 vk::VkDeviceSize stride) const
100 {
101 vk::VkVertexInputBindingDescription2EXT bindingDescription = vk::initVulkanStructure();
102 bindingDescription.binding = 0u;
103 bindingDescription.stride = (uint32_t)stride;
104 bindingDescription.inputRate = vk::VK_VERTEX_INPUT_RATE_VERTEX;
105 bindingDescription.divisor = 1u;
106 vk::VkVertexInputAttributeDescription2EXT attributeDescription = vk::initVulkanStructure();
107 attributeDescription.location = 0u;
108 attributeDescription.binding = 0u;
109 attributeDescription.format = vk::VK_FORMAT_R32G32B32A32_SFLOAT;
110 attributeDescription.offset = 0u;
111 vk.cmdSetVertexInputEXT(cmdBuffer, 1u, &bindingDescription, 1u, &attributeDescription);
112 }
113
bindVertexBuffers(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkDeviceSize * stride,vk::VkBuffer buffer,vk::VkDeviceSize bufferSize) const114 void ShaderObjectMiscInstance::bindVertexBuffers(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer,
115 vk::VkDeviceSize *stride, vk::VkBuffer buffer,
116 vk::VkDeviceSize bufferSize) const
117 {
118 vk::VkDeviceSize offset = 0u;
119 vk.cmdBindVertexBuffers2(cmdBuffer, 0u, 1u, &buffer, &offset, &bufferSize, stride);
120 }
121
iterate(void)122 tcu::TestStatus ShaderObjectMiscInstance::iterate(void)
123 {
124 const vk::VkInstance instance = m_context.getInstance();
125 const vk::InstanceDriver instanceDriver(m_context.getPlatformInterface(), instance);
126 const vk::DeviceInterface &vk = m_context.getDeviceInterface();
127 const vk::VkDevice device = m_context.getDevice();
128 const vk::VkQueue queue = m_context.getUniversalQueue();
129 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
130 auto &alloc = m_context.getDefaultAllocator();
131 tcu::TestLog &log = m_context.getTestContext().getLog();
132 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(
133 m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
134 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
135 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
136 const bool taskSupported = m_context.getMeshShaderFeatures().taskShader;
137 const bool meshSupported = m_context.getMeshShaderFeatures().meshShader;
138
139 vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
140 const auto subresourceRange = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
141 const auto subresourceLayers = vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
142 const vk::VkRect2D renderArea = vk::makeRect2D(0, 0, 32, 32);
143 vk::VkExtent3D extent = {renderArea.extent.width, renderArea.extent.height, 1};
144
145 const vk::VkImageCreateInfo createInfo = {
146 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
147 DE_NULL, // const void* pNext
148 0u, // VkImageCreateFlags flags
149 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
150 colorAttachmentFormat, // VkFormat format
151 {32, 32, 1}, // VkExtent3D extent
152 1u, // uint32_t mipLevels
153 1u, // uint32_t arrayLayers
154 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
155 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
156 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
157 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
158 0, // uint32_t queueFamilyIndexCount
159 DE_NULL, // const uint32_t* pQueueFamilyIndices
160 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
161 };
162
163 const uint32_t colorAttachmentCount = 2;
164
165 std::vector<de::MovePtr<vk::ImageWithMemory>> images(colorAttachmentCount);
166 std::vector<vk::Move<vk::VkImageView>> imageViews(colorAttachmentCount);
167 for (uint32_t i = 0; i < colorAttachmentCount; ++i)
168 {
169 images[i] = de::MovePtr<vk::ImageWithMemory>(
170 new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
171 imageViews[i] = vk::makeImageView(vk, device, **images[i], vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat,
172 subresourceRange);
173 }
174
175 const vk::VkDeviceSize colorOutputBufferSize =
176 renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
177 std::vector<de::MovePtr<vk::BufferWithMemory>> colorOutputBuffers(colorAttachmentCount);
178 for (uint32_t i = 0; i < colorAttachmentCount; ++i)
179 {
180 colorOutputBuffers[i] = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
181 vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT),
182 vk::MemoryRequirement::HostVisible));
183 }
184
185 const vk::Move<vk::VkCommandPool> cmdPool(vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
186 const vk::Move<vk::VkCommandBuffer> cmdBuffer(
187 vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
188
189 vk::Move<vk::VkDescriptorSetLayout> descriptorSetLayout(
190 vk::DescriptorSetLayoutBuilder()
191 .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_FRAGMENT_BIT)
192 .build(vk, device));
193
194 const vk::Unique<vk::VkDescriptorPool> descriptorPool(
195 vk::DescriptorPoolBuilder()
196 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
197 .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
198
199 const vk::VkDeviceSize bufferSizeBytes = sizeof(tcu::Vec4);
200 const vk::Unique<vk::VkDescriptorSet> descriptorSet(
201 makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
202 const vk::BufferWithMemory inputBuffer(
203 vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
204 vk::MemoryRequirement::HostVisible);
205
206 const vk::VkDescriptorBufferInfo descriptorInfo = vk::makeDescriptorBufferInfo(*inputBuffer, 0ull, bufferSizeBytes);
207 vk::DescriptorSetUpdateBuilder()
208 .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u),
209 vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
210 .update(vk, device);
211 const auto pipelineLayout = makePipelineLayout(vk, device, *descriptorSetLayout);
212
213 float *inputDataPtr = reinterpret_cast<float *>(inputBuffer.getAllocation().getHostPtr());
214 memset(inputDataPtr, 0, bufferSizeBytes);
215 for (uint32_t i = 0; i < 4; ++i)
216 inputDataPtr[i] = 0.5f;
217 flushAlloc(vk, device, inputBuffer.getAllocation());
218
219 const auto &binaries = m_context.getBinaryCollection();
220 const auto vertShader =
221 vk::createShader(vk, device,
222 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("inputVert"),
223 tessellationSupported, geometrySupported, &*descriptorSetLayout));
224 const auto fragShader =
225 vk::createShader(vk, device,
226 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("multiFrag"),
227 tessellationSupported, geometrySupported, &*descriptorSetLayout));
228
229 const vk::VkClearValue clearValue = vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 0.0f});
230 vk::beginCommandBuffer(vk, *cmdBuffer);
231
232 for (uint32_t i = 0; i < colorAttachmentCount; ++i)
233 {
234 vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(
235 vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
236 vk::VK_IMAGE_LAYOUT_GENERAL, **images[i], subresourceRange);
237 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
238 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u,
239 (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
240 &preImageBarrier);
241 }
242
243 std::vector<vk::VkRenderingAttachmentInfoKHR> colorAttachments(colorAttachmentCount);
244 vk::VkRenderingAttachmentInfoKHR colorAttachment{
245 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
246 DE_NULL, // const void* pNext;
247 VK_NULL_HANDLE, // VkImageView imageView;
248 vk::VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
249 vk::VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
250 DE_NULL, // VkImageView resolveImageView;
251 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
252 vk::VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
253 vk::VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
254 clearValue // VkClearValue clearValue;
255 };
256
257 for (uint32_t i = 0; i < colorAttachmentCount; ++i)
258 {
259 colorAttachment.imageView = *imageViews[i];
260 colorAttachments[i] = colorAttachment;
261 }
262
263 vk::VkRenderingInfoKHR renderingInfo{
264 vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
265 DE_NULL,
266 (vk::VkRenderingFlags)0u, // VkRenderingFlagsKHR flags;
267 renderArea, // VkRect2D renderArea;
268 1u, // uint32_t layerCount;
269 0x0, // uint32_t viewMask;
270 (uint32_t)colorAttachments.size(), // uint32_t colorAttachmentCount;
271 colorAttachments.data(), // const VkRenderingAttachmentInfoKHR* pColorAttachments;
272 DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
273 DE_NULL, // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
274 };
275
276 const vk::VkDeviceSize bufferSize = 1024;
277 de::MovePtr<vk::BufferWithMemory> buffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
278 vk, device, alloc, vk::makeBufferCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
279 vk::MemoryRequirement::HostVisible));
280 float *dataPtr = reinterpret_cast<float *>(buffer->getAllocation().getHostPtr());
281 memset(dataPtr, 0, bufferSize);
282 for (uint32_t i = 0; i < 4; ++i)
283 {
284 dataPtr[i * (m_params.stride / sizeof(float)) + 0] = float(i & 1);
285 dataPtr[i * (m_params.stride / sizeof(float)) + 1] = float((i >> 1) & 1);
286 dataPtr[i * (m_params.stride / sizeof(float)) + 2] = 0.0f;
287 dataPtr[i * (m_params.stride / sizeof(float)) + 3] = 1.0f;
288 }
289 flushAlloc(vk, device, buffer->getAllocation());
290
291 vk::Move<vk::VkDescriptorSetLayout> null;
292 if (m_params.destroyDescriptorSetLayout)
293 descriptorSetLayout = null;
294
295 vk.cmdBeginRendering(*cmdBuffer, &renderingInfo);
296 vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
297 false);
298
299 vk::VkColorBlendEquationEXT colorBlendEquation = {
300 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
301 vk::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor;
302 vk::VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
303 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
304 vk::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstAlphaBlendFactor;
305 vk::VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
306 };
307 vk::VkColorComponentFlags colorWriteMask = vk::VK_COLOR_COMPONENT_R_BIT | vk::VK_COLOR_COMPONENT_G_BIT |
308 vk::VK_COLOR_COMPONENT_B_BIT | vk::VK_COLOR_COMPONENT_A_BIT;
309 for (uint32_t i = 0; i < colorAttachmentCount; ++i)
310 {
311 vk::VkBool32 colorBlendEnable = m_params.blendEnabled[i] ? VK_TRUE : VK_FALSE;
312 vk.cmdSetColorBlendEnableEXT(*cmdBuffer, i, 1u, &colorBlendEnable);
313 if (m_params.blendEnabled[i])
314 {
315 vk.cmdSetColorBlendEquationEXT(*cmdBuffer, i, 1u, &colorBlendEquation);
316 }
317 vk.cmdSetColorWriteMaskEXT(*cmdBuffer, i, 1u, &colorWriteMask);
318 }
319 const vk::VkPhysicalDeviceProperties properties =
320 vk::getPhysicalDeviceProperties(instanceDriver, m_context.getPhysicalDevice());
321 std::vector<vk::VkBool32> colorWriteEnables(properties.limits.maxColorAttachments);
322 for (uint32_t i = 0; i < properties.limits.maxColorAttachments; ++i)
323 {
324 colorWriteEnables[i] = i < colorAttachmentCount ? VK_TRUE : VK_FALSE;
325 }
326 vk.cmdSetColorWriteEnableEXT(*cmdBuffer, properties.limits.maxColorAttachments, colorWriteEnables.data());
327
328 if (m_params.vertexInputBefore)
329 setVertexInput(vk, *cmdBuffer, m_params.vertexBuffersNullStride ? m_params.stride : 100);
330
331 vk::VkDeviceSize stride = m_params.stride;
332 vk::VkDeviceSize *pStride = m_params.vertexBuffersNullStride ? DE_NULL : &stride;
333 bindVertexBuffers(vk, *cmdBuffer, pStride, **buffer, bufferSize);
334
335 if (!m_params.vertexInputBefore)
336 setVertexInput(vk, *cmdBuffer, m_params.stride);
337
338 vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0, 1,
339 &descriptorSet.get(), 0, DE_NULL);
340
341 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, *fragShader,
342 taskSupported, meshSupported);
343 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
344 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
345
346 vk::endRendering(vk, *cmdBuffer);
347
348 for (uint32_t i = 0; i < colorAttachmentCount; ++i)
349 {
350 vk::VkImageMemoryBarrier postImageBarrier = vk::makeImageMemoryBarrier(
351 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL,
352 vk::VK_IMAGE_LAYOUT_GENERAL, **images[i], subresourceRange);
353 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
354 vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u,
355 (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
356 &postImageBarrier);
357 }
358
359 const vk::VkBufferImageCopy copyRegion = vk::makeBufferImageCopy(extent, subresourceLayers);
360 for (uint32_t i = 0; i < colorAttachmentCount; ++i)
361 vk.cmdCopyImageToBuffer(*cmdBuffer, **images[i], vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffers[i], 1u,
362 ©Region);
363
364 vk::endCommandBuffer(vk, *cmdBuffer);
365
366 vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
367
368 const int32_t width = renderArea.extent.width;
369 const int32_t height = renderArea.extent.height;
370 const float threshold = 1.0f / 256.0f;
371 const int32_t xOffset = width / 8;
372 const int32_t yOffset = height / 8;
373 const tcu::Vec4 refColor1 = tcu::Vec4(0.75f, 0.75f, 0.75f, 0.75f);
374 const tcu::Vec4 refColor2 = tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f);
375 const tcu::Vec4 blackColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
376
377 for (uint32_t k = 0; k < colorAttachmentCount; ++k)
378 {
379 tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(
380 vk::mapVkFormat(colorAttachmentFormat), renderArea.extent.width, renderArea.extent.height, 1,
381 (const void *)colorOutputBuffers[k]->getAllocation().getHostPtr());
382 for (int32_t j = 0; j < height; ++j)
383 {
384 for (int32_t i = 0; i < width; ++i)
385 {
386 const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
387
388 tcu::Vec4 expectedColor = blackColor;
389 if (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset)
390 {
391 if (m_params.blendEnabled[k])
392 expectedColor = refColor1;
393 else
394 expectedColor = refColor2;
395 }
396
397 if (deFloatAbs(color.x() - expectedColor.x()) > threshold ||
398 deFloatAbs(color.y() - expectedColor.y()) > threshold ||
399 deFloatAbs(color.z() - expectedColor.z()) > threshold ||
400 deFloatAbs(color.w() - expectedColor.w()) > threshold)
401 {
402 log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") was " << color
403 << ", but expected color was " << expectedColor << tcu::TestLog::EndMessage;
404 return tcu::TestStatus::fail("Fail");
405 }
406 }
407 }
408 }
409
410 return tcu::TestStatus::pass("Pass");
411 }
412
413 class ShaderObjectMiscCase : public vkt::TestCase
414 {
415 public:
ShaderObjectMiscCase(tcu::TestContext & testCtx,const std::string & name,const TestParams & params)416 ShaderObjectMiscCase(tcu::TestContext &testCtx, const std::string &name, const TestParams ¶ms)
417 : vkt::TestCase(testCtx, name)
418 , m_params(params)
419 {
420 }
~ShaderObjectMiscCase(void)421 virtual ~ShaderObjectMiscCase(void)
422 {
423 }
424
425 void checkSupport(vkt::Context &context) const override;
426 virtual void initPrograms(vk::SourceCollections &programCollection) const override;
createInstance(Context & context) const427 TestInstance *createInstance(Context &context) const override
428 {
429 return new ShaderObjectMiscInstance(context, m_params);
430 }
431
432 private:
433 TestParams m_params;
434 };
435
checkSupport(Context & context) const436 void ShaderObjectMiscCase::checkSupport(Context &context) const
437 {
438 context.requireDeviceFunctionality("VK_EXT_shader_object");
439 }
440
initPrograms(vk::SourceCollections & programCollection) const441 void ShaderObjectMiscCase::initPrograms(vk::SourceCollections &programCollection) const
442 {
443 std::stringstream inputVert;
444 std::stringstream multiFrag;
445
446 inputVert << "#version 450\n"
447 << "layout(location = 0) in vec4 inPos;\n"
448 << "void main() {\n"
449 << " gl_Position = vec4((inPos.xy - 0.5f) * 1.5f, inPos.zw);\n"
450 << "}\n";
451
452 multiFrag << "#version 450\n"
453 << "layout(set=0, binding=0) readonly buffer inputBuf {\n"
454 << " vec4 color;\n"
455 << "};\n"
456 << "layout (location=0) out vec4 outColor0;\n"
457 << "layout (location=1) out vec4 outColor1;\n"
458 << "void main() {\n"
459 << " outColor0 = color;\n"
460 << " outColor1 = color;\n"
461 << "}\n";
462
463 programCollection.glslSources.add("inputVert") << glu::VertexSource(inputVert.str());
464 programCollection.glslSources.add("multiFrag") << glu::FragmentSource(multiFrag.str());
465 }
466
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)467 de::MovePtr<tcu::TextureLevel> readDepthAttachment(const vk::DeviceInterface &vk, vk::VkDevice device,
468 vk::VkQueue queue, uint32_t queueFamilyIndex,
469 vk::Allocator &allocator, vk::VkImage image, vk::VkFormat format,
470 const tcu::UVec2 &renderSize, vk::VkImageLayout currentLayout)
471 {
472 vk::Move<vk::VkBuffer> buffer;
473 de::MovePtr<vk::Allocation> bufferAlloc;
474 vk::Move<vk::VkCommandPool> cmdPool;
475 vk::Move<vk::VkCommandBuffer> cmdBuffer;
476
477 tcu::TextureFormat retFormat(tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST);
478 tcu::TextureFormat bufferFormat(tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST);
479 const vk::VkImageAspectFlags barrierAspect =
480 vk::VK_IMAGE_ASPECT_DEPTH_BIT |
481 (mapVkFormat(format).order == tcu::TextureFormat::DS ? vk::VK_IMAGE_ASPECT_STENCIL_BIT :
482 (vk::VkImageAspectFlagBits)0);
483
484 switch (format)
485 {
486 case vk::VK_FORMAT_D16_UNORM:
487 case vk::VK_FORMAT_D16_UNORM_S8_UINT:
488 bufferFormat.type = retFormat.type = tcu::TextureFormat::UNORM_INT16;
489 break;
490 case vk::VK_FORMAT_D24_UNORM_S8_UINT:
491 case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
492 retFormat.type = tcu::TextureFormat::UNORM_INT24;
493 // vkCmdCopyBufferToImage copies D24 data to 32-bit pixels.
494 bufferFormat.type = tcu::TextureFormat::UNSIGNED_INT_24_8_REV;
495 break;
496 case vk::VK_FORMAT_D32_SFLOAT:
497 case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
498 bufferFormat.type = retFormat.type = tcu::TextureFormat::FLOAT;
499 break;
500 default:
501 TCU_FAIL("unrecognized format");
502 }
503
504 const vk::VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * bufferFormat.getPixelSize();
505 de::MovePtr<tcu::TextureLevel> resultLevel(new tcu::TextureLevel(retFormat, renderSize.x(), renderSize.y()));
506
507 // Create destination buffer
508 {
509 const vk::VkBufferCreateInfo bufferParams = {
510 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
511 DE_NULL, // const void* pNext;
512 0u, // VkBufferCreateFlags flags;
513 pixelDataSize, // VkDeviceSize size;
514 vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
515 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
516 0u, // uint32_t queueFamilyIndexCount;
517 DE_NULL // const uint32_t* pQueueFamilyIndices;
518 };
519
520 buffer = createBuffer(vk, device, &bufferParams);
521 bufferAlloc =
522 allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), vk::MemoryRequirement::HostVisible);
523 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
524 }
525
526 // Create command pool and buffer
527 cmdPool = createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
528 cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
529
530 beginCommandBuffer(vk, *cmdBuffer);
531 copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()),
532 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, currentLayout, 1u, barrierAspect,
533 vk::VK_IMAGE_ASPECT_DEPTH_BIT);
534 endCommandBuffer(vk, *cmdBuffer);
535
536 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
537
538 // Read buffer data
539 invalidateAlloc(vk, device, *bufferAlloc);
540 tcu::copy(*resultLevel,
541 tcu::ConstPixelBufferAccess(bufferFormat, resultLevel->getSize(), bufferAlloc->getHostPtr()));
542
543 return resultLevel;
544 }
545
readStencilAttachment(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)546 de::MovePtr<tcu::TextureLevel> readStencilAttachment(const vk::DeviceInterface &vk, vk::VkDevice device,
547 vk::VkQueue queue, uint32_t queueFamilyIndex,
548 vk::Allocator &allocator, vk::VkImage image, vk::VkFormat format,
549 const tcu::UVec2 &renderSize, vk::VkImageLayout currentLayout)
550 {
551 vk::Move<vk::VkBuffer> buffer;
552 de::MovePtr<vk::Allocation> bufferAlloc;
553 vk::Move<vk::VkCommandPool> cmdPool;
554 vk::Move<vk::VkCommandBuffer> cmdBuffer;
555
556 tcu::TextureFormat retFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
557 tcu::TextureFormat bufferFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
558
559 const vk::VkImageAspectFlags barrierAspect =
560 vk::VK_IMAGE_ASPECT_STENCIL_BIT |
561 (mapVkFormat(format).order == tcu::TextureFormat::DS ? vk::VK_IMAGE_ASPECT_DEPTH_BIT :
562 (vk::VkImageAspectFlagBits)0);
563 const vk::VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * bufferFormat.getPixelSize();
564 de::MovePtr<tcu::TextureLevel> resultLevel(new tcu::TextureLevel(retFormat, renderSize.x(), renderSize.y()));
565
566 // Create destination buffer
567 {
568 const vk::VkBufferCreateInfo bufferParams = {
569 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
570 DE_NULL, // const void* pNext;
571 0u, // VkBufferCreateFlags flags;
572 pixelDataSize, // VkDeviceSize size;
573 vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
574 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
575 0u, // uint32_t queueFamilyIndexCount;
576 DE_NULL // const uint32_t* pQueueFamilyIndices;
577 };
578
579 buffer = createBuffer(vk, device, &bufferParams);
580 bufferAlloc =
581 allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), vk::MemoryRequirement::HostVisible);
582 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
583 }
584
585 // Create command pool and buffer
586 cmdPool = createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
587 cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
588
589 beginCommandBuffer(vk, *cmdBuffer);
590 copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()),
591 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, currentLayout, 1u, barrierAspect,
592 vk::VK_IMAGE_ASPECT_STENCIL_BIT);
593 endCommandBuffer(vk, *cmdBuffer);
594
595 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
596
597 // Read buffer data
598 invalidateAlloc(vk, device, *bufferAlloc);
599 tcu::copy(*resultLevel,
600 tcu::ConstPixelBufferAccess(bufferFormat, resultLevel->getSize(), bufferAlloc->getHostPtr()));
601
602 return resultLevel;
603 }
604
605 struct StateTestParams
606 {
607 bool pipeline;
608 bool meshShader;
609 bool vertShader;
610 bool tessShader;
611 bool geomShader;
612 bool fragShader;
613 bool logicOp;
614 bool alphaToOne;
615 bool depthBounds;
616 bool depthClamp;
617 bool depthClip;
618 bool depthClipControl;
619 bool colorWrite;
620 bool geometryStreams;
621 bool discardRectangles;
622 bool conservativeRasterization;
623 bool rasterizerDiscardEnable;
624 bool lines;
625 bool sampleLocations;
626 bool provokingVertex;
627 bool lineRasterization;
628 bool cull;
629 bool stencilTestEnable;
630 bool depthTestEnable;
631 bool depthBiasEnable;
632 bool depthBoundsTestEnable;
633 bool logicOpEnable;
634 bool colorBlendEnable;
635 bool discardRectanglesEnable;
636 bool sampleLocationsEnable;
637 bool conservativeRasterizationOverestimate;
638 bool stippledLineEnable;
639 bool colorWriteEnable;
640
resetvkt::ShaderObject::__anonea3521b10111::StateTestParams641 void reset()
642 {
643 logicOp = false;
644 alphaToOne = false;
645 depthBounds = false;
646 depthClamp = false;
647 depthClip = false;
648 depthClipControl = false;
649 colorWrite = true;
650 geometryStreams = false;
651 discardRectangles = false;
652 conservativeRasterization = false;
653 rasterizerDiscardEnable = false;
654 lines = false;
655 sampleLocations = false;
656 provokingVertex = false;
657 lineRasterization = false;
658 cull = false;
659 stencilTestEnable = false;
660 depthTestEnable = false;
661 depthBiasEnable = false;
662 depthBoundsTestEnable = false;
663 logicOpEnable = false;
664 colorBlendEnable = false;
665 discardRectanglesEnable = false;
666 sampleLocationsEnable = false;
667 conservativeRasterizationOverestimate = false;
668 stippledLineEnable = false;
669 colorWriteEnable = true;
670 }
671 };
672
673 class ShaderObjectStateInstance : public vkt::TestInstance
674 {
675 public:
ShaderObjectStateInstance(Context & context,const StateTestParams & testParams)676 ShaderObjectStateInstance(Context &context, const StateTestParams &testParams)
677 : vkt::TestInstance(context)
678 , m_params(testParams)
679 {
680 }
~ShaderObjectStateInstance(void)681 virtual ~ShaderObjectStateInstance(void)
682 {
683 }
684
685 tcu::TestStatus iterate(void) override;
686
687 private:
688 void createDevice(void);
689 std::vector<vk::VkDynamicState> getDynamicStates(void) const;
690 bool hasDynamicState(const std::vector<vk::VkDynamicState> dynamicStates, const vk::VkDynamicState dynamicState);
691 void setDynamicStates(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer);
692 bool isInsidePrimitive(uint32_t i, uint32_t j, uint32_t width, uint32_t height);
693
694 vk::Move<vk::VkDevice> m_customDevice;
695 de::MovePtr<vk::DeviceDriver> m_logicalDeviceInterface;
696 vk::VkQueue m_logicalDeviceQueue;
697 const StateTestParams m_params;
698 };
699
createDevice(void)700 void ShaderObjectStateInstance::createDevice(void)
701 {
702 vk::VkPhysicalDeviceMeshShaderFeaturesEXT meshShaderFeatuers = vk::initVulkanStructure();
703 vk::VkPhysicalDeviceColorWriteEnableFeaturesEXT colorWriteEnableFeatures = vk::initVulkanStructure();
704 vk::VkPhysicalDeviceDepthClipControlFeaturesEXT depthClipControlFeatures = vk::initVulkanStructure();
705 vk::VkPhysicalDeviceDepthClipEnableFeaturesEXT depthClipEnableFeatures = vk::initVulkanStructure();
706 vk::VkPhysicalDeviceTransformFeedbackFeaturesEXT transformFeedbackFeatures = vk::initVulkanStructure();
707 vk::VkPhysicalDeviceLineRasterizationFeaturesEXT lineRasterizationFeatures = vk::initVulkanStructure();
708
709 vk::VkPhysicalDeviceDynamicRenderingFeatures dynamicRenderingFeatures = m_context.getDynamicRenderingFeatures();
710 vk::VkPhysicalDeviceShaderObjectFeaturesEXT shaderObjectFeatures = m_context.getShaderObjectFeaturesEXT();
711
712 vk::VkPhysicalDeviceExtendedDynamicStateFeaturesEXT edsFeatures = m_context.getExtendedDynamicStateFeaturesEXT();
713 vk::VkPhysicalDeviceExtendedDynamicState2FeaturesEXT eds2Features = m_context.getExtendedDynamicState2FeaturesEXT();
714 vk::VkPhysicalDeviceExtendedDynamicState3FeaturesEXT eds3Features = m_context.getExtendedDynamicState3FeaturesEXT();
715 vk::VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT viFeatures =
716 m_context.getVertexInputDynamicStateFeaturesEXT();
717
718 dynamicRenderingFeatures.pNext = DE_NULL;
719 shaderObjectFeatures.pNext = DE_NULL;
720 edsFeatures.pNext = DE_NULL;
721 eds2Features.pNext = DE_NULL;
722 eds3Features.pNext = DE_NULL;
723 viFeatures.pNext = DE_NULL;
724
725 vk::VkPhysicalDeviceFeatures2 features2 = vk::initVulkanStructure();
726 void *pNext = &dynamicRenderingFeatures;
727
728 const float queuePriority = 1.0f;
729 std::vector<const char *> deviceExtensions = {"VK_KHR_dynamic_rendering"};
730 if (m_params.pipeline)
731 {
732 const auto &deviceExts = m_context.getDeviceExtensions();
733 if (std::find(deviceExts.begin(), deviceExts.end(), "VK_EXT_extended_dynamic_state") != deviceExts.end())
734 {
735 deviceExtensions.push_back("VK_EXT_extended_dynamic_state");
736 edsFeatures.pNext = pNext;
737 pNext = &edsFeatures;
738 }
739 if (std::find(deviceExts.begin(), deviceExts.end(), "VK_EXT_extended_dynamic_state2") != deviceExts.end())
740 {
741 deviceExtensions.push_back("VK_EXT_extended_dynamic_state2");
742 eds2Features.pNext = pNext;
743 pNext = &eds2Features;
744 }
745 if (std::find(deviceExts.begin(), deviceExts.end(), "VK_EXT_extended_dynamic_state3") != deviceExts.end())
746 {
747 deviceExtensions.push_back("VK_EXT_extended_dynamic_state3");
748 eds3Features.pNext = pNext;
749 pNext = &eds3Features;
750 }
751 if (std::find(deviceExts.begin(), deviceExts.end(), "VK_EXT_vertex_input_dynamic_state") != deviceExts.end())
752 {
753 deviceExtensions.push_back("VK_EXT_vertex_input_dynamic_state");
754 viFeatures.pNext = pNext;
755 pNext = &viFeatures;
756 }
757 }
758 else
759 {
760 deviceExtensions.push_back("VK_EXT_shader_object");
761 dynamicRenderingFeatures.pNext = &shaderObjectFeatures;
762 }
763
764 if (m_params.tessShader)
765 features2.features.tessellationShader = VK_TRUE;
766 if (m_params.geomShader)
767 features2.features.geometryShader = VK_TRUE;
768
769 if (m_params.logicOp)
770 features2.features.logicOp = VK_TRUE;
771 if (m_params.alphaToOne)
772 features2.features.alphaToOne = VK_TRUE;
773 if (m_params.depthBounds)
774 features2.features.depthBounds = VK_TRUE;
775 if (m_params.depthClamp)
776 features2.features.depthClamp = VK_TRUE;
777 if (m_params.depthBiasEnable)
778 features2.features.depthBiasClamp = VK_TRUE;
779 if (m_params.depthClip)
780 {
781 depthClipEnableFeatures.pNext = pNext;
782 pNext = &depthClipEnableFeatures;
783 depthClipEnableFeatures.depthClipEnable = VK_TRUE;
784 deviceExtensions.push_back("VK_EXT_depth_clip_enable");
785 }
786 if (m_params.depthClipControl)
787 {
788 depthClipControlFeatures.pNext = pNext;
789 pNext = &depthClipControlFeatures;
790 depthClipControlFeatures.depthClipControl = VK_TRUE;
791 deviceExtensions.push_back("VK_EXT_depth_clip_control");
792 }
793 if (m_params.colorWrite)
794 {
795 colorWriteEnableFeatures.pNext = pNext;
796 pNext = &colorWriteEnableFeatures;
797 colorWriteEnableFeatures.colorWriteEnable = VK_TRUE;
798 deviceExtensions.push_back("VK_EXT_color_write_enable");
799 }
800 if (m_params.geometryStreams)
801 {
802 transformFeedbackFeatures.pNext = pNext;
803 pNext = &transformFeedbackFeatures;
804 transformFeedbackFeatures.transformFeedback = VK_TRUE;
805 transformFeedbackFeatures.geometryStreams = VK_TRUE;
806 deviceExtensions.push_back("VK_EXT_transform_feedback");
807 }
808 if (m_params.sampleLocations)
809 deviceExtensions.push_back("VK_EXT_sample_locations");
810 if (m_params.discardRectangles)
811 deviceExtensions.push_back("VK_EXT_discard_rectangles");
812 if (m_params.conservativeRasterization)
813 deviceExtensions.push_back("VK_EXT_conservative_rasterization");
814 if (m_params.sampleLocations)
815 deviceExtensions.push_back("VK_EXT_sample_locations");
816 if (m_params.provokingVertex)
817 deviceExtensions.push_back("VK_EXT_provoking_vertex");
818 if (m_params.lineRasterization)
819 {
820 lineRasterizationFeatures.pNext = pNext;
821 pNext = &lineRasterizationFeatures;
822 lineRasterizationFeatures.rectangularLines = VK_TRUE;
823 const auto &deviceExts = m_context.getDeviceExtensions();
824 if (std::find(deviceExts.begin(), deviceExts.end(), "VK_KHR_line_rasterization") != deviceExts.end())
825 {
826 deviceExtensions.push_back("VK_KHR_line_rasterization");
827 }
828 else
829 {
830 deviceExtensions.push_back("VK_EXT_line_rasterization");
831 }
832 }
833 if (m_params.meshShader)
834 {
835 meshShaderFeatuers.pNext = pNext;
836 pNext = &meshShaderFeatuers;
837 meshShaderFeatuers.meshShader = VK_TRUE;
838 deviceExtensions.push_back("VK_EXT_mesh_shader");
839 }
840
841 features2.pNext = pNext;
842
843 vk::VkDeviceQueueCreateInfo queueInfo = {
844 vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
845 DE_NULL, // const void* pNext;
846 0u, // VkDeviceQueueCreateFlags flags;
847 0u, // uint32_t queueFamilyIndex;
848 1u, // uint32_t queueCount;
849 &queuePriority // const float* pQueuePriorities;
850 };
851
852 const vk::VkDeviceCreateInfo deviceInfo = {
853 vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType;
854 &features2, // const void* pNext;
855 (vk::VkDeviceCreateFlags)0, // VkDeviceCreateFlags flags;
856 1u, // uint32_t queueCreateInfoCount;
857 &queueInfo, // const VkDeviceQueueCreateInfo* pQueueCreateInfos;
858 0u, // uint32_t enabledLayerCount;
859 DE_NULL, // const char* const* ppEnabledLayerNames;
860 uint32_t(deviceExtensions.size()), // uint32_t enabledExtensionCount;
861 deviceExtensions.data(), // const char* const* ppEnabledExtensionNames;
862 DE_NULL // const VkPhysicalDeviceFeatures* pEnabledFeatures;
863 };
864
865 m_customDevice = createCustomDevice(m_context.getTestContext().getCommandLine().isValidationEnabled(),
866 m_context.getPlatformInterface(), m_context.getInstance(),
867 m_context.getInstanceInterface(), m_context.getPhysicalDevice(), &deviceInfo);
868 m_logicalDeviceInterface = de::MovePtr<vk::DeviceDriver>(
869 new vk::DeviceDriver(m_context.getPlatformInterface(), m_context.getInstance(), *m_customDevice,
870 m_context.getUsedApiVersion(), m_context.getTestContext().getCommandLine()));
871 m_logicalDeviceInterface->getDeviceQueue(*m_customDevice, m_context.getUniversalQueueFamilyIndex(), 0,
872 &m_logicalDeviceQueue);
873 }
874
getDynamicStates(void) const875 std::vector<vk::VkDynamicState> ShaderObjectStateInstance::getDynamicStates(void) const
876 {
877 const auto &edsFeatures = m_context.getExtendedDynamicStateFeaturesEXT();
878 const auto &eds2Features = m_context.getExtendedDynamicState2FeaturesEXT();
879 const auto &eds3Features = m_context.getExtendedDynamicState3FeaturesEXT();
880 const auto &viFeatures = m_context.getVertexInputDynamicStateFeaturesEXT();
881
882 std::vector<vk::VkDynamicState> dynamicStates;
883
884 if (edsFeatures.extendedDynamicState)
885 {
886 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT);
887 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT);
888 }
889
890 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_WIDTH);
891 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BIAS);
892 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_BLEND_CONSTANTS);
893 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS);
894 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK);
895 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_WRITE_MASK);
896 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_REFERENCE);
897 if (edsFeatures.extendedDynamicState && !m_params.meshShader && !m_params.pipeline)
898 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE);
899 if (edsFeatures.extendedDynamicState)
900 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CULL_MODE);
901 if (edsFeatures.extendedDynamicState)
902 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE);
903 if (edsFeatures.extendedDynamicState)
904 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_COMPARE_OP);
905 if (edsFeatures.extendedDynamicState)
906 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE);
907 if (edsFeatures.extendedDynamicState)
908 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE);
909 if (edsFeatures.extendedDynamicState)
910 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_FRONT_FACE);
911 if (edsFeatures.extendedDynamicState && !m_params.meshShader)
912 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY);
913 if (edsFeatures.extendedDynamicState)
914 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_OP);
915 if (edsFeatures.extendedDynamicState)
916 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE);
917 if (eds2Features.extendedDynamicState2)
918 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE);
919 if (eds2Features.extendedDynamicState2 && !m_params.meshShader)
920 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE);
921 if (eds2Features.extendedDynamicState2)
922 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT);
923 if (viFeatures.vertexInputDynamicState && !m_params.meshShader && !m_params.pipeline)
924 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT);
925 if (eds2Features.extendedDynamicState2LogicOp)
926 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LOGIC_OP_EXT);
927 if (eds2Features.extendedDynamicState2PatchControlPoints && !m_params.meshShader)
928 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT);
929 if (eds3Features.extendedDynamicState3TessellationDomainOrigin)
930 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT);
931 if (eds3Features.extendedDynamicState3DepthClampEnable)
932 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT);
933 if (eds3Features.extendedDynamicState3PolygonMode)
934 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT);
935 if (eds3Features.extendedDynamicState3RasterizationSamples)
936 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT);
937 if (eds3Features.extendedDynamicState3SampleMask)
938 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_MASK_EXT);
939 if (eds3Features.extendedDynamicState3AlphaToCoverageEnable)
940 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT);
941 if (eds3Features.extendedDynamicState3AlphaToOneEnable)
942 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT);
943 if (eds3Features.extendedDynamicState3LogicOpEnable)
944 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT);
945 if (eds3Features.extendedDynamicState3ColorBlendEnable)
946 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT);
947 if (eds3Features.extendedDynamicState3ColorBlendEquation)
948 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT);
949 if (eds3Features.extendedDynamicState3ColorWriteMask)
950 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT);
951 if (eds3Features.extendedDynamicState3RasterizationStream && m_params.geometryStreams)
952 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT);
953 if (m_params.discardRectangles)
954 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT);
955 if (m_params.discardRectangles)
956 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT);
957 if (m_params.discardRectangles)
958 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT);
959 if (eds3Features.extendedDynamicState3ConservativeRasterizationMode && m_params.conservativeRasterization)
960 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT);
961 if (eds3Features.extendedDynamicState3ExtraPrimitiveOverestimationSize && m_params.conservativeRasterization)
962 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT);
963 if (eds3Features.extendedDynamicState3DepthClipEnable && m_params.depthClip)
964 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT);
965 if (eds3Features.extendedDynamicState3SampleLocationsEnable && m_params.sampleLocations)
966 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT);
967 if (m_params.sampleLocations)
968 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT);
969 if (eds3Features.extendedDynamicState3ProvokingVertexMode && m_params.provokingVertex)
970 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT);
971 if (eds3Features.extendedDynamicState3LineRasterizationMode && m_params.lineRasterization)
972 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT);
973 if (eds3Features.extendedDynamicState3LineStippleEnable && m_params.lineRasterization)
974 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT);
975 if (m_params.lineRasterization)
976 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_EXT);
977 if (eds3Features.extendedDynamicState3DepthClipNegativeOneToOne && m_params.depthClipControl)
978 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT);
979 if (m_params.colorWrite)
980 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT);
981 return dynamicStates;
982 }
983
hasDynamicState(const std::vector<vk::VkDynamicState> dynamicStates,const vk::VkDynamicState dynamicState)984 bool ShaderObjectStateInstance::hasDynamicState(const std::vector<vk::VkDynamicState> dynamicStates,
985 const vk::VkDynamicState dynamicState)
986 {
987 if (!m_params.pipeline)
988 return false;
989 return std::find(dynamicStates.begin(), dynamicStates.end(), dynamicState) != dynamicStates.end();
990 }
991
extensionEnabled(const std::vector<std::string> & deviceExtensions,const std::string & ext)992 bool extensionEnabled(const std::vector<std::string> &deviceExtensions, const std::string &ext)
993 {
994 return std::find(deviceExtensions.begin(), deviceExtensions.end(), ext) != deviceExtensions.end();
995 }
996
setDynamicStates(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer)997 void ShaderObjectStateInstance::setDynamicStates(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer)
998 {
999 const auto dynamicStates = getDynamicStates();
1000 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(
1001 m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
1002
1003 vk::VkViewport viewport = {
1004 0, 0, 32, 32, 0.0f, 1.0f,
1005 };
1006 if (m_params.depthClamp)
1007 viewport.maxDepth = 0.5f;
1008 if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT))
1009 vk.cmdSetViewportWithCount(cmdBuffer, 1u, &viewport);
1010 vk::VkRect2D scissor = {
1011 {
1012 0,
1013 0,
1014 },
1015 {
1016 32,
1017 32,
1018 },
1019 };
1020 if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT))
1021 vk.cmdSetScissorWithCount(cmdBuffer, 1u, &scissor);
1022 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.lines) ||
1023 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LINE_WIDTH))
1024 vk.cmdSetLineWidth(cmdBuffer, 1.0f);
1025 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.depthBiasEnable))
1026 vk.cmdSetDepthBias(cmdBuffer, 4.0f, 1.0f, 4.0f);
1027 else if (hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_BIAS))
1028 vk.cmdSetDepthBias(cmdBuffer, 1.0f, 0.0f, 1.0f);
1029 float blendConstants[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1030 if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable && m_params.colorBlendEnable) ||
1031 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_BLEND_CONSTANTS))
1032 vk.cmdSetBlendConstants(cmdBuffer, blendConstants);
1033 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.depthBoundsTestEnable) ||
1034 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS))
1035 vk.cmdSetDepthBounds(cmdBuffer, 0.2f, 0.3f);
1036 vk.cmdSetStencilCompareMask(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFFFFFFF);
1037 vk.cmdSetStencilWriteMask(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFFFFFFF);
1038 vk.cmdSetStencilReference(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFFFFFFF);
1039 if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE))
1040 vk.cmdBindVertexBuffers2(cmdBuffer, 0, 0, DE_NULL, DE_NULL, DE_NULL, DE_NULL);
1041 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1042 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_CULL_MODE))
1043 vk.cmdSetCullMode(cmdBuffer, m_params.cull ? vk::VK_CULL_MODE_FRONT_AND_BACK : vk::VK_CULL_MODE_NONE);
1044 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.depthBounds) ||
1045 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE))
1046 vk.cmdSetDepthBoundsTestEnable(cmdBuffer, m_params.depthBoundsTestEnable ? VK_TRUE : VK_FALSE);
1047 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1048 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_COMPARE_OP))
1049 vk.cmdSetDepthCompareOp(cmdBuffer, vk::VK_COMPARE_OP_LESS);
1050 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1051 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE))
1052 vk.cmdSetDepthTestEnable(cmdBuffer, m_params.depthTestEnable ? VK_TRUE : VK_FALSE);
1053 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1054 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE))
1055 vk.cmdSetDepthWriteEnable(cmdBuffer, VK_TRUE);
1056 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && (m_params.cull || m_params.stencilTestEnable)) ||
1057 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_FRONT_FACE))
1058 vk.cmdSetFrontFace(cmdBuffer, vk::VK_FRONT_FACE_CLOCKWISE);
1059 if ((!m_params.pipeline && m_params.vertShader) ||
1060 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY))
1061 {
1062 if (m_params.tessShader)
1063 vk.cmdSetPrimitiveTopology(cmdBuffer, vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
1064 else if (m_params.lines)
1065 vk.cmdSetPrimitiveTopology(cmdBuffer, vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST);
1066 else
1067 vk.cmdSetPrimitiveTopology(cmdBuffer, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
1068 }
1069 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.stencilTestEnable) ||
1070 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_STENCIL_OP))
1071 vk.cmdSetStencilOp(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, vk::VK_STENCIL_OP_REPLACE,
1072 vk::VK_STENCIL_OP_REPLACE, vk::VK_STENCIL_OP_REPLACE, vk::VK_COMPARE_OP_GREATER);
1073 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1074 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE))
1075 vk.cmdSetStencilTestEnable(cmdBuffer, m_params.stencilTestEnable ? VK_TRUE : VK_FALSE);
1076 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1077 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE))
1078 vk.cmdSetDepthBiasEnable(cmdBuffer, m_params.depthBiasEnable ? VK_TRUE : VK_FALSE);
1079 if ((!m_params.pipeline && m_params.vertShader) ||
1080 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE))
1081 vk.cmdSetPrimitiveRestartEnable(cmdBuffer, VK_FALSE);
1082 if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE))
1083 vk.cmdSetRasterizerDiscardEnable(cmdBuffer, m_params.rasterizerDiscardEnable ? VK_TRUE : VK_FALSE);
1084 if ((!m_params.pipeline && m_params.vertShader) ||
1085 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE))
1086 if (extensionEnabled(deviceExtensions, "VK_EXT_shader_object") ||
1087 extensionEnabled(deviceExtensions, "VK_EXT_vertex_input_dynamic_state"))
1088 vk.cmdSetVertexInputEXT(cmdBuffer, 0u, DE_NULL, 0u, DE_NULL);
1089 if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable && m_params.logicOpEnable) ||
1090 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LOGIC_OP_EXT))
1091 vk.cmdSetLogicOpEXT(cmdBuffer, vk::VK_LOGIC_OP_COPY);
1092 if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT))
1093 vk.cmdSetPatchControlPointsEXT(cmdBuffer, 4u);
1094 if ((!m_params.pipeline && m_params.tessShader) ||
1095 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT))
1096 vk.cmdSetTessellationDomainOriginEXT(cmdBuffer, vk::VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT);
1097 if (!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.depthClamp)
1098 vk.cmdSetDepthClampEnableEXT(cmdBuffer, VK_TRUE);
1099 else if (hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT))
1100 vk.cmdSetDepthClampEnableEXT(cmdBuffer, m_params.depthClamp ? VK_TRUE : VK_FALSE);
1101 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1102 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT))
1103 vk.cmdSetPolygonModeEXT(cmdBuffer, vk::VK_POLYGON_MODE_FILL);
1104 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1105 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT))
1106 vk.cmdSetRasterizationSamplesEXT(cmdBuffer, vk::VK_SAMPLE_COUNT_1_BIT);
1107 vk::VkSampleMask sampleMask = 0xFFFFFFFF;
1108 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1109 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_SAMPLE_MASK_EXT))
1110 vk.cmdSetSampleMaskEXT(cmdBuffer, vk::VK_SAMPLE_COUNT_1_BIT, &sampleMask);
1111 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1112 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT))
1113 vk.cmdSetAlphaToCoverageEnableEXT(cmdBuffer, VK_FALSE);
1114 if (!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.alphaToOne)
1115 vk.cmdSetAlphaToOneEnableEXT(cmdBuffer, VK_TRUE);
1116 else if (hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT))
1117 vk.cmdSetAlphaToOneEnableEXT(cmdBuffer, m_params.alphaToOne ? VK_TRUE : VK_FALSE);
1118 if (!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable && m_params.logicOp)
1119 vk.cmdSetLogicOpEnableEXT(cmdBuffer, m_params.logicOpEnable ? VK_TRUE : VK_FALSE);
1120 else if (hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT))
1121 vk.cmdSetLogicOpEnableEXT(cmdBuffer, m_params.logicOpEnable ? VK_TRUE : VK_FALSE);
1122 vk::VkBool32 colorBlendEnable = m_params.colorBlendEnable ? VK_TRUE : VK_FALSE;
1123 if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable) ||
1124 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT))
1125 vk.cmdSetColorBlendEnableEXT(cmdBuffer, 0u, 1u, &colorBlendEnable);
1126 vk::VkColorBlendEquationEXT colorBlendEquation = {
1127 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
1128 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor;
1129 vk::VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
1130 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
1131 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor;
1132 vk::VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
1133 };
1134 if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable) ||
1135 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT))
1136 vk.cmdSetColorBlendEquationEXT(cmdBuffer, 0u, 1u, &colorBlendEquation);
1137 vk::VkColorComponentFlags colorWriteMask = vk::VK_COLOR_COMPONENT_R_BIT | vk::VK_COLOR_COMPONENT_G_BIT |
1138 vk::VK_COLOR_COMPONENT_B_BIT | vk::VK_COLOR_COMPONENT_A_BIT;
1139 if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable) ||
1140 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT))
1141 vk.cmdSetColorWriteMaskEXT(cmdBuffer, 0u, 1u, &colorWriteMask);
1142 if ((!m_params.pipeline && m_params.geomShader && m_params.geometryStreams) ||
1143 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT))
1144 vk.cmdSetRasterizationStreamEXT(cmdBuffer, 0u);
1145 if (m_params.discardRectangles)
1146 vk.cmdSetDiscardRectangleEnableEXT(cmdBuffer, m_params.discardRectanglesEnable ? VK_TRUE : VK_FALSE);
1147 if ((!m_params.pipeline && m_params.discardRectanglesEnable) ||
1148 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT))
1149 vk.cmdSetDiscardRectangleModeEXT(cmdBuffer, vk::VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT);
1150 if ((!m_params.pipeline && m_params.discardRectanglesEnable) ||
1151 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT))
1152 vk.cmdSetDiscardRectangleEXT(cmdBuffer, 0u, 1u, &scissor);
1153 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.conservativeRasterization) ||
1154 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT))
1155 vk.cmdSetConservativeRasterizationModeEXT(cmdBuffer,
1156 m_params.conservativeRasterizationOverestimate ?
1157 vk::VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT :
1158 vk::VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT);
1159 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.conservativeRasterization &&
1160 m_params.conservativeRasterizationOverestimate) ||
1161 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT))
1162 vk.cmdSetExtraPrimitiveOverestimationSizeEXT(
1163 cmdBuffer,
1164 de::min(1.0f, m_context.getConservativeRasterizationPropertiesEXT().maxExtraPrimitiveOverestimationSize));
1165 if ((!m_params.pipeline && m_params.depthClip) ||
1166 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT))
1167 vk.cmdSetDepthClipEnableEXT(cmdBuffer, VK_TRUE);
1168 if ((!m_params.pipeline && m_params.sampleLocations) ||
1169 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT))
1170 vk.cmdSetSampleLocationsEnableEXT(cmdBuffer, m_params.sampleLocationsEnable ? VK_TRUE : VK_FALSE);
1171 vk::VkSampleLocationEXT sampleLocation = {0.5f, 0.5f};
1172 const vk::VkSampleLocationsInfoEXT sampleLocationsInfo = {
1173 vk::VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT, // VkStructureType sType;
1174 DE_NULL, // const void* pNext;
1175 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits sampleLocationsPerPixel;
1176 {1u, 1u}, // VkExtent2D sampleLocationGridSize;
1177 1, // uint32_t sampleLocationsCount;
1178 &sampleLocation, // const VkSampleLocationEXT* pSampleLocations;
1179 };
1180 if ((!m_params.pipeline && m_params.sampleLocations && m_params.sampleLocationsEnable) ||
1181 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT))
1182 vk.cmdSetSampleLocationsEXT(cmdBuffer, &sampleLocationsInfo);
1183 if ((!m_params.pipeline && m_params.provokingVertex) ||
1184 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT))
1185 vk.cmdSetProvokingVertexModeEXT(cmdBuffer, vk::VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT);
1186 if (m_params.pipeline || (!m_params.rasterizerDiscardEnable && m_params.lineRasterization && m_params.lines))
1187 {
1188 if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT))
1189 vk.cmdSetLineRasterizationModeEXT(cmdBuffer, vk::VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT);
1190 if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT))
1191 vk.cmdSetLineStippleEnableEXT(cmdBuffer, m_params.stippledLineEnable ? VK_TRUE : VK_FALSE);
1192 if ((!m_params.pipeline && m_params.stippledLineEnable) ||
1193 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LINE_STIPPLE_EXT))
1194 vk.cmdSetLineStippleKHR(cmdBuffer, 1u, 0x1);
1195 }
1196 if ((!m_params.pipeline && m_params.depthClipControl) ||
1197 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT))
1198 vk.cmdSetDepthClipNegativeOneToOneEXT(cmdBuffer, VK_TRUE);
1199 vk::VkBool32 colorWriteEnable = m_params.colorWriteEnable ? VK_TRUE : VK_FALSE;
1200 if ((!m_params.pipeline && m_params.colorWrite) ||
1201 hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT))
1202 vk.cmdSetColorWriteEnableEXT(cmdBuffer, 1u, &colorWriteEnable);
1203 }
1204
isInsidePrimitive(uint32_t i,uint32_t j,uint32_t width,uint32_t height)1205 bool ShaderObjectStateInstance::isInsidePrimitive(uint32_t i, uint32_t j, uint32_t width, uint32_t height)
1206 {
1207 uint32_t xOffset = width / 4;
1208 uint32_t yOffset = height / 4;
1209 if (m_params.tessShader)
1210 xOffset /= 2;
1211 if (m_params.geomShader)
1212 yOffset /= 2;
1213
1214 bool inside = false;
1215 if (m_params.lines)
1216 {
1217 if (m_params.stippledLineEnable)
1218 {
1219 if (m_params.tessShader && m_params.geomShader)
1220 inside = (j == 4 && i == 3) || (j == 20 && i == 3);
1221 else if (m_params.tessShader)
1222 inside = (j == 8 && i == 3);
1223 else if (m_params.geomShader)
1224 inside = (j == 3 && i == 8) || (j == 27 && i == 8);
1225 else
1226 inside = (j == 7 && i == 8) || (j == 23 && i == 8);
1227 }
1228 else
1229 {
1230 if (m_params.tessShader && m_params.geomShader)
1231 inside = m_params.lines && (i == 3 && (j >= 4 && j < 28));
1232 else if (m_params.tessShader)
1233 inside = m_params.lines && (i == 3 && (j >= 8 && j < 24));
1234 else if (m_params.geomShader)
1235 inside = m_params.lines && ((j == 3 || j == 27) && (i >= 8 && i < 24));
1236 else
1237 inside = m_params.lines && (i >= 8 && i < 24 && (j == 7 || j == 23));
1238 }
1239 }
1240 else
1241 {
1242 inside = !m_params.lines && (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset);
1243 }
1244 return inside;
1245 }
1246
iterate(void)1247 tcu::TestStatus ShaderObjectStateInstance::iterate(void)
1248 {
1249 const vk::VkInstance instance = m_context.getInstance();
1250 const vk::InstanceDriver instanceDriver(m_context.getPlatformInterface(), instance);
1251 createDevice();
1252 const vk::DeviceInterface &vk = *m_logicalDeviceInterface;
1253 const vk::VkDevice device = *m_customDevice;
1254 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1255 const vk::VkQueue queue = m_logicalDeviceQueue;
1256 auto alloctor = de::MovePtr<vk::Allocator>(new vk::SimpleAllocator(
1257 vk, device, getPhysicalDeviceMemoryProperties(instanceDriver, m_context.getPhysicalDevice())));
1258 auto &alloc = *alloctor;
1259 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(
1260 m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
1261 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
1262 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
1263 tcu::TestLog &log = m_context.getTestContext().getLog();
1264
1265 vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
1266 vk::VkFormat depthStencilAttachmentFormat =
1267 findDSFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice());
1268 const auto subresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1269 const auto subresourceLayers = vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
1270 auto depthSubresourceRange =
1271 vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, 1u);
1272 const vk::VkRect2D renderArea = vk::makeRect2D(0, 0, 32, 32);
1273 vk::VkExtent3D extent = {renderArea.extent.width, renderArea.extent.height, 1};
1274
1275 const bool taskSupported = m_context.getMeshShaderFeatures().taskShader;
1276 const bool meshSupported = m_context.getMeshShaderFeatures().meshShader;
1277
1278 const vk::VkImageCreateInfo createInfo = {
1279 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
1280 DE_NULL, // const void* pNext
1281 0u, // VkImageCreateFlags flags
1282 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
1283 colorAttachmentFormat, // VkFormat format
1284 {32, 32, 1}, // VkExtent3D extent
1285 1u, // uint32_t mipLevels
1286 1u, // uint32_t arrayLayers
1287 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
1288 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
1289 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
1290 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
1291 0, // uint32_t queueFamilyIndexCount
1292 DE_NULL, // const uint32_t* pQueueFamilyIndices
1293 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
1294 };
1295
1296 const vk::VkImageCreateInfo depthCreateInfo = {
1297 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
1298 DE_NULL, // const void* pNext
1299 0u, // VkImageCreateFlags flags
1300 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
1301 depthStencilAttachmentFormat, // VkFormat format
1302 {32, 32, 1}, // VkExtent3D extent
1303 1u, // uint32_t mipLevels
1304 1u, // uint32_t arrayLayers
1305 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
1306 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
1307 vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
1308 vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
1309 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
1310 0, // uint32_t queueFamilyIndexCount
1311 DE_NULL, // const uint32_t* pQueueFamilyIndices
1312 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
1313 };
1314
1315 de::MovePtr<vk::ImageWithMemory> image = de::MovePtr<vk::ImageWithMemory>(
1316 new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
1317 const auto imageView =
1318 vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
1319
1320 de::MovePtr<vk::ImageWithMemory> depthImage = de::MovePtr<vk::ImageWithMemory>(
1321 new vk::ImageWithMemory(vk, device, alloc, depthCreateInfo, vk::MemoryRequirement::Any));
1322 const auto depthImageView = vk::makeImageView(vk, device, **depthImage, vk::VK_IMAGE_VIEW_TYPE_2D,
1323 depthStencilAttachmentFormat, depthSubresourceRange);
1324
1325 const vk::VkDeviceSize colorOutputBufferSize =
1326 renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
1327 de::MovePtr<vk::BufferWithMemory> colorOutputBuffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
1328 vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT),
1329 vk::MemoryRequirement::HostVisible));
1330
1331 const vk::Move<vk::VkCommandPool> cmdPool(vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
1332 const vk::Move<vk::VkCommandBuffer> cmdBuffer(
1333 vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1334
1335 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
1336 vk::DescriptorSetLayoutBuilder()
1337 .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1338 vk::VK_SHADER_STAGE_ALL_GRAPHICS | vk::VK_SHADER_STAGE_MESH_BIT_EXT)
1339 .build(vk, device));
1340
1341 const vk::Unique<vk::VkDescriptorPool> descriptorPool(
1342 vk::DescriptorPoolBuilder()
1343 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
1344 .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
1345
1346 const vk::VkDeviceSize bufferSizeBytes = sizeof(uint32_t) * 8;
1347 const vk::Unique<vk::VkDescriptorSet> descriptorSet(
1348 makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
1349 const vk::BufferWithMemory outputBuffer(
1350 vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
1351 vk::MemoryRequirement::HostVisible);
1352
1353 const vk::VkDescriptorBufferInfo descriptorInfo =
1354 vk::makeDescriptorBufferInfo(*outputBuffer, 0ull, bufferSizeBytes);
1355 vk::DescriptorSetUpdateBuilder()
1356 .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u),
1357 vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
1358 .update(vk, device);
1359
1360 const auto pipelineLayout = makePipelineLayout(vk, device, *descriptorSetLayout);
1361
1362 const auto &binaries = m_context.getBinaryCollection();
1363 vk::Move<vk::VkPipeline> pipeline;
1364 vk::Move<vk::VkShaderEXT> meshShader;
1365 vk::Move<vk::VkShaderEXT> vertShader;
1366 vk::Move<vk::VkShaderEXT> tescShader;
1367 vk::Move<vk::VkShaderEXT> teseShader;
1368 vk::Move<vk::VkShaderEXT> geomShader;
1369 vk::Move<vk::VkShaderEXT> fragShader;
1370
1371 if (m_params.pipeline)
1372 {
1373 vk::Move<vk::VkShaderModule> meshShaderModule;
1374 vk::Move<vk::VkShaderModule> vertShaderModule;
1375 vk::Move<vk::VkShaderModule> tescShaderModule;
1376 vk::Move<vk::VkShaderModule> teseShaderModule;
1377 vk::Move<vk::VkShaderModule> geomShaderModule;
1378 vk::Move<vk::VkShaderModule> fragShaderModule;
1379 if (m_params.meshShader)
1380 meshShaderModule = vk::createShaderModule(vk, device, binaries.get("mesh"));
1381 if (m_params.vertShader)
1382 vertShaderModule = vk::createShaderModule(vk, device, binaries.get("vert"));
1383 if (m_params.tessShader)
1384 tescShaderModule = vk::createShaderModule(vk, device, binaries.get("tesc"));
1385 if (m_params.tessShader)
1386 teseShaderModule = vk::createShaderModule(vk, device, binaries.get("tese"));
1387 if (m_params.geomShader)
1388 geomShaderModule = vk::createShaderModule(vk, device, binaries.get("geom"));
1389 if (m_params.fragShader)
1390 fragShaderModule = vk::createShaderModule(vk, device, binaries.get("frag"));
1391
1392 const vk::VkPipelineVertexInputStateCreateInfo vertexInputState = {
1393 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1394 DE_NULL, // const void* pNext;
1395 (vk::VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
1396 0u, // uint32_t vertexBindingDescriptionCount;
1397 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1398 0u, // uint32_t vertexAttributeDescriptionCount;
1399 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1400 };
1401
1402 vk::VkPrimitiveTopology topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
1403 if (m_params.tessShader)
1404 topology = vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
1405 else if (m_params.lines)
1406 topology = vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
1407
1408 const vk::VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = {
1409 vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1410 DE_NULL, // const void* pNext;
1411 (vk::VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
1412 topology, // VkPrimitiveTopology topology;
1413 VK_FALSE // VkBool32 primitiveRestartEnable;
1414 };
1415
1416 const vk::VkPipelineTessellationStateCreateInfo tessellationState = {
1417 vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
1418 DE_NULL, // const void* pNext;
1419 (vk::VkPipelineTessellationStateCreateFlags)0u, // VkPipelineTessellationStateCreateFlags flags;
1420 4u // uint32_t patchControlPoints;
1421 };
1422
1423 const vk::VkPipelineRasterizationDepthClipStateCreateInfoEXT depthClipState = {
1424 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT, // VkStructureType sType;
1425 DE_NULL, // const void* pNext;
1426 (vk::VkPipelineRasterizationDepthClipStateCreateFlagsEXT)0u, // VkPipelineRasterizationDepthClipStateCreateFlagsEXT flags;
1427 m_params.depthClip // VkBool32 depthClipEnable;
1428 };
1429
1430 const vk::VkPipelineRasterizationStateCreateInfo rasterizationState = {
1431 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1432 m_params.depthClip ? &depthClipState : DE_NULL, // const void* pNext;
1433 (vk::VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
1434 m_params.depthClamp, // VkBool32 depthClampEnable;
1435 m_params.rasterizerDiscardEnable, // VkBool32 rasterizerDiscardEnable;
1436 vk::VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
1437 m_params.cull ? (vk::VkCullModeFlags)vk::VK_CULL_MODE_FRONT_AND_BACK :
1438 (vk::VkCullModeFlags)vk::VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
1439 vk::VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace;
1440 m_params.depthBiasEnable ? VK_TRUE : VK_FALSE, // VkBool32 depthBiasEnable;
1441 0.0f, // float depthBiasConstantFactor;
1442 0.0f, // float depthBiasClamp;
1443 0.0f, // float depthBiasSlopeFactor;
1444 1.0f // float lineWidth;
1445 };
1446
1447 const vk::VkPipelineMultisampleStateCreateInfo multisampleState = {
1448 vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType
1449 DE_NULL, // const void* pNext
1450 (vk::VkPipelineMultisampleStateCreateFlags)0u, // VkPipelineMultisampleStateCreateFlags flags
1451 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples
1452 VK_FALSE, // VkBool32 sampleShadingEnable
1453 1.0f, // float minSampleShading
1454 DE_NULL, // const VkSampleMask* pSampleMask
1455 VK_FALSE, // VkBool32 alphaToCoverageEnable
1456 m_params.alphaToOne ? VK_TRUE : VK_FALSE // VkBool32 alphaToOneEnable
1457 };
1458
1459 const auto stencilOp = (m_params.stencilTestEnable ? vk::VK_STENCIL_OP_REPLACE : vk::VK_STENCIL_OP_KEEP);
1460 const auto stencilCompareOp =
1461 (m_params.stencilTestEnable ? vk::VK_COMPARE_OP_GREATER : vk::VK_COMPARE_OP_ALWAYS);
1462
1463 const vk::VkStencilOpState stencilOpState = vk::makeStencilOpState(stencilOp, // stencil fail
1464 stencilOp, // depth & stencil pass
1465 stencilOp, // depth only fail
1466 stencilCompareOp, // compare op
1467 0u, // compare mask
1468 0u, // write mask
1469 0u); // reference
1470
1471 const vk::VkPipelineDepthStencilStateCreateInfo depthStencilState{
1472 vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
1473 DE_NULL, // const void* pNext
1474 (vk::VkPipelineDepthStencilStateCreateFlags)0u, // VkPipelineDepthStencilStateCreateFlags flags
1475 m_params.depthTestEnable ? VK_TRUE : VK_FALSE, // VkBool32 depthTestEnable
1476 VK_TRUE, // VkBool32 depthWriteEnable
1477 vk::VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp
1478 m_params.depthBoundsTestEnable ? VK_TRUE :
1479 VK_FALSE, // VkBool32 depthBoundsTestEnable
1480 m_params.stencilTestEnable ? VK_TRUE :
1481 VK_FALSE, // VkBool32 stencilTestEnable
1482 stencilOpState, // VkStencilOpState front
1483 stencilOpState, // VkStencilOpState back
1484 0.0f, // float minDepthBounds
1485 1.0f, // float maxDepthBounds
1486 };
1487
1488 const vk::VkPipelineColorBlendAttachmentState colorBlendAttState = {
1489 m_params.colorBlendEnable ? VK_TRUE : VK_FALSE, // VkBool32 blendEnable;
1490 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
1491 vk::VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
1492 vk::VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
1493 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
1494 vk::VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
1495 vk::VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
1496 vk::VK_COLOR_COMPONENT_R_BIT | vk::VK_COLOR_COMPONENT_G_BIT | vk::VK_COLOR_COMPONENT_B_BIT |
1497 vk::VK_COLOR_COMPONENT_A_BIT, // VkColorComponentFlags colorWriteMask;
1498 };
1499
1500 const uint32_t colorAttachmentCount = 2;
1501 const vk::VkPhysicalDeviceProperties properties =
1502 vk::getPhysicalDeviceProperties(instanceDriver, m_context.getPhysicalDevice());
1503 std::vector<vk::VkBool32> colorWriteEnables(properties.limits.maxColorAttachments);
1504 for (uint32_t i = 0; i < properties.limits.maxColorAttachments; ++i)
1505 {
1506 colorWriteEnables[i] = i < colorAttachmentCount ? VK_TRUE : VK_FALSE;
1507 }
1508 const vk::VkPipelineColorWriteCreateInfoEXT colorWriteState = {
1509 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT, // VkStructureType sType;
1510 DE_NULL, // const void* pNext;
1511 (uint32_t)colorWriteEnables.size(), // uint32_t attachmentCount;
1512 colorWriteEnables.data() // const VkBool32* pColorWriteEnables;
1513 };
1514
1515 const vk::VkPipelineColorBlendStateCreateInfo colorBlendState = {
1516 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1517 m_params.colorWrite ? &colorWriteState : DE_NULL, // const void* pNext;
1518 (vk::VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
1519 m_params.logicOpEnable ? VK_TRUE : VK_FALSE, // VkBool32 logicOpEnable;
1520 vk::VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1521 1u, // uint32_t attachmentCount;
1522 &colorBlendAttState, // const VkPipelineColorBlendAttachmentState* pAttachments;
1523 {0.0f, 0.0f, 0.0f, 0.0f}, // float blendConstants[4];
1524 };
1525
1526 vk::VkViewport viewport = {
1527 0, 0, 32, 32, 0.0f, 1.0f,
1528 };
1529 vk::VkRect2D scissor = {
1530 {
1531 0,
1532 0,
1533 },
1534 {
1535 32,
1536 32,
1537 },
1538 };
1539
1540 const auto &edsFeatures = m_context.getExtendedDynamicStateFeaturesEXT();
1541 uint32_t viewportAndScissorCount = edsFeatures.extendedDynamicState ? 0u : 1u;
1542
1543 const vk::VkPipelineViewportDepthClipControlCreateInfoEXT depthClipControlState = {
1544 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT, // VkStructureType sType;
1545 DE_NULL, // const void* pNext;
1546 VK_TRUE, // VkBool32 negativeOneToOne;
1547 };
1548
1549 const vk::VkPipelineViewportStateCreateInfo viewportState = {
1550 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType
1551 m_params.depthClipControl ? &depthClipControlState :
1552 DE_NULL, // const void* pNext
1553 (vk::VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags
1554 viewportAndScissorCount, // uint32_t viewportCount
1555 &viewport, // const VkViewport* pViewports
1556 viewportAndScissorCount, // uint32_t scissorCount
1557 &scissor // const VkRect2D* pScissors
1558 };
1559
1560 const auto dynamicStates = getDynamicStates();
1561
1562 const vk::VkPipelineDynamicStateCreateInfo dynamicState = {
1563 vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType
1564 DE_NULL, // const void* pNext
1565 0u, // VkPipelineDynamicStateCreateFlags flags
1566 (uint32_t)dynamicStates.size(), // uint32_t dynamicStateCount
1567 dynamicStates.data(), // const VkDynamicState* pDynamicStates
1568 };
1569
1570 const vk::VkPipelineRenderingCreateInfo pipelineRenderingCreateInfo = {
1571 vk::VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, // VkStructureType sType
1572 DE_NULL, // const void* pNext
1573 0u, // uint32_t viewMask
1574 1u, // uint32_t colorAttachmentCount
1575 &colorAttachmentFormat, // const VkFormat* pColorAttachmentFormats
1576 depthStencilAttachmentFormat, // VkFormat depthAttachmentFormat
1577 depthStencilAttachmentFormat, // VkFormat stencilAttachmentFormat
1578 };
1579
1580 if (m_params.meshShader)
1581 pipeline = vk::makeGraphicsPipeline(vk, device, *pipelineLayout, VK_NULL_HANDLE, *meshShaderModule,
1582 *fragShaderModule, VK_NULL_HANDLE, {}, {}, 0u, &rasterizationState,
1583 &multisampleState, &depthStencilState, &colorBlendState, &dynamicState,
1584 0u, &pipelineRenderingCreateInfo);
1585 else
1586 pipeline = vk::makeGraphicsPipeline(
1587 vk, device, *pipelineLayout, *vertShaderModule, *tescShaderModule, *teseShaderModule, *geomShaderModule,
1588 *fragShaderModule, VK_NULL_HANDLE, 0u, &vertexInputState, &inputAssemblyState, &tessellationState,
1589 &viewportState, &rasterizationState, &multisampleState, &depthStencilState, &colorBlendState,
1590 &dynamicState, &pipelineRenderingCreateInfo);
1591 }
1592 else
1593 {
1594 if (m_params.meshShader)
1595 {
1596 auto meshShaderCreateInfo =
1597 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_MESH_BIT_EXT, binaries.get("mesh"), tessellationSupported,
1598 geometrySupported, &*descriptorSetLayout);
1599 meshShaderCreateInfo.flags = vk::VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT;
1600 meshShader = vk::createShader(vk, device, meshShaderCreateInfo);
1601 }
1602 if (m_params.vertShader)
1603 vertShader = vk::createShader(vk, device,
1604 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("vert"),
1605 tessellationSupported, geometrySupported,
1606 &*descriptorSetLayout));
1607 if (m_params.tessShader)
1608 tescShader = vk::createShader(vk, device,
1609 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
1610 binaries.get("tesc"), tessellationSupported,
1611 geometrySupported, &*descriptorSetLayout));
1612 if (m_params.tessShader)
1613 teseShader = vk::createShader(vk, device,
1614 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
1615 binaries.get("tese"), tessellationSupported,
1616 geometrySupported, &*descriptorSetLayout));
1617 if (m_params.geomShader)
1618 geomShader = vk::createShader(vk, device,
1619 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_GEOMETRY_BIT,
1620 binaries.get("geom"), tessellationSupported,
1621 geometrySupported, &*descriptorSetLayout));
1622 if (m_params.fragShader)
1623 fragShader = vk::createShader(vk, device,
1624 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT,
1625 binaries.get("frag"), tessellationSupported,
1626 geometrySupported, &*descriptorSetLayout));
1627 }
1628
1629 const vk::VkDeviceSize tfBufSize = 4 * sizeof(tcu::Vec4);
1630 vk::Move<vk::VkBuffer> tfBuf;
1631 de::MovePtr<vk::Allocation> tfBufAllocation;
1632 const vk::VkMemoryBarrier tfMemoryBarrier =
1633 vk::makeMemoryBarrier(vk::VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, vk::VK_ACCESS_HOST_READ_BIT);
1634 if (m_params.geometryStreams)
1635 {
1636 const vk::VkBufferCreateInfo tfBufCreateInfo = vk::makeBufferCreateInfo(
1637 tfBufSize, vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT | vk::VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
1638 tfBuf = createBuffer(vk, device, &tfBufCreateInfo);
1639 tfBufAllocation =
1640 alloc.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), vk::MemoryRequirement::HostVisible);
1641 vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset());
1642 }
1643
1644 const vk::VkClearValue clearValue = vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 0.0f});
1645 const vk::VkClearValue clearDepthValue = vk::makeClearValueDepthStencil(1.0f, 0u);
1646 vk::beginCommandBuffer(vk, *cmdBuffer);
1647
1648 vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0, 1,
1649 &descriptorSet.get(), 0, DE_NULL);
1650
1651 vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(
1652 vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
1653 vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
1654 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1655 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u,
1656 (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
1657 &preImageBarrier);
1658
1659 vk::VkImageMemoryBarrier preDepthImageBarrier = vk::makeImageMemoryBarrier(
1660 vk::VK_ACCESS_NONE, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
1661 vk::VK_IMAGE_LAYOUT_GENERAL, **depthImage, depthSubresourceRange);
1662 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1663 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, (vk::VkDependencyFlags)0u, 0u,
1664 (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
1665 &preDepthImageBarrier);
1666
1667 vk::beginRendering(vk, *cmdBuffer, *imageView, *depthImageView, true, renderArea, clearValue, clearDepthValue,
1668 vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
1669
1670 if (m_params.pipeline)
1671 {
1672 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1673 }
1674 else
1675 {
1676 if (m_params.meshShader)
1677 {
1678 vk::VkShaderStageFlagBits stages[] = {
1679 vk::VK_SHADER_STAGE_MESH_BIT_EXT,
1680 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
1681 };
1682 vk::VkShaderEXT shaders[] = {
1683 *meshShader,
1684 *fragShader,
1685 };
1686 vk::bindNullRasterizationShaders(vk, *cmdBuffer, m_context.getDeviceFeatures());
1687 vk.cmdBindShadersEXT(*cmdBuffer, 2, stages, shaders);
1688 }
1689 else
1690 {
1691 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, *tescShader, *teseShader, *geomShader, *fragShader,
1692 taskSupported, meshSupported);
1693 }
1694 }
1695 setDynamicStates(vk, *cmdBuffer);
1696
1697 if (m_params.geometryStreams)
1698 {
1699 vk::VkDeviceSize offset = 0u;
1700 vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, 1, &*tfBuf, &offset, &tfBufSize);
1701 vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0u, DE_NULL, DE_NULL);
1702 }
1703
1704 bool secondDraw = !m_params.depthClamp && !m_params.depthClip;
1705 if (m_params.meshShader)
1706 {
1707 if (secondDraw)
1708 vk.cmdDrawMeshTasksEXT(*cmdBuffer, 2, 1, 1);
1709 else
1710 vk.cmdDrawMeshTasksEXT(*cmdBuffer, 1, 1, 1);
1711 }
1712 else
1713 {
1714 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
1715 if (secondDraw)
1716 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 1);
1717 }
1718 if (m_params.geometryStreams)
1719 vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0u, DE_NULL, DE_NULL);
1720 vk::endRendering(vk, *cmdBuffer);
1721
1722 vk::VkImageMemoryBarrier postImageBarrier =
1723 vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT,
1724 vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
1725 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1726 vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u,
1727 (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
1728 &postImageBarrier);
1729
1730 vk::VkImageMemoryBarrier postDepthImageBarrier = vk::makeImageMemoryBarrier(
1731 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL,
1732 vk::VK_IMAGE_LAYOUT_GENERAL, **depthImage, depthSubresourceRange);
1733 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
1734 (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier *)DE_NULL, 0u,
1735 (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u, &postDepthImageBarrier);
1736
1737 vk::VkBufferMemoryBarrier bufferBarrier = vk::makeBufferMemoryBarrier(
1738 vk::VK_ACCESS_SHADER_WRITE_BIT, vk::VK_ACCESS_HOST_READ_BIT, *outputBuffer, 0u, bufferSizeBytes);
1739 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT,
1740 (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier *)DE_NULL, 1u, &bufferBarrier, 0u,
1741 (const vk::VkImageMemoryBarrier *)DE_NULL);
1742
1743 if (m_params.geometryStreams)
1744 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT,
1745 vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &tfMemoryBarrier, 0u, DE_NULL, 0u, DE_NULL);
1746
1747 const vk::VkBufferImageCopy copyRegion = vk::makeBufferImageCopy(extent, subresourceLayers);
1748 vk.cmdCopyImageToBuffer(*cmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u, ©Region);
1749
1750 vk::endCommandBuffer(vk, *cmdBuffer);
1751 vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1752
1753 tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(
1754 vk::mapVkFormat(colorAttachmentFormat), renderArea.extent.width, renderArea.extent.height, 1,
1755 (const void *)colorOutputBuffer->getAllocation().getHostPtr());
1756
1757 const int32_t width = resultBuffer.getWidth();
1758 const int32_t height = resultBuffer.getHeight();
1759 const float threshold = 1.0f / 256.0f;
1760 tcu::Vec4 whiteColor = tcu::Vec4(0.75f);
1761 tcu::Vec4 blackColor = tcu::Vec4(0.0f);
1762
1763 const vk::Allocation &outputBufferAllocation = outputBuffer.getAllocation();
1764 invalidateAlloc(vk, device, outputBufferAllocation);
1765
1766 const uint32_t *bufferPtr = static_cast<uint32_t *>(outputBufferAllocation.getHostPtr());
1767
1768 if (m_params.geometryStreams)
1769 {
1770 invalidateAlloc(vk, device, *tfBufAllocation);
1771 const float *tfData = static_cast<float *>(tfBufAllocation->getHostPtr());
1772 uint32_t count = m_params.lines ? 2 : 3;
1773 for (uint32_t i = 0; i < count; ++i)
1774 {
1775 for (uint32_t j = 0; j < 4; ++j)
1776 {
1777 if (tfData[i * 4 + j] != float(i + 1))
1778 {
1779 return tcu::TestStatus::fail("Fail");
1780 }
1781 }
1782 }
1783 return tcu::TestStatus::pass("Pass");
1784 }
1785
1786 if (m_params.vertShader)
1787 {
1788 if (bufferPtr[0] != 1u)
1789 {
1790 log << tcu::TestLog::Message << "Buffer value at index 0 was expected to be 1, but was[" << bufferPtr[0]
1791 << tcu::TestLog::EndMessage;
1792 return tcu::TestStatus::fail("Fail");
1793 }
1794 }
1795
1796 if (m_params.tessShader)
1797 {
1798 if (bufferPtr[1] != 2u)
1799 {
1800 log << tcu::TestLog::Message << "Buffer value at index 1 was expected to be 2, but was[" << bufferPtr[1]
1801 << tcu::TestLog::EndMessage;
1802 return tcu::TestStatus::fail("Fail");
1803 }
1804 if (bufferPtr[2] != 3u)
1805 {
1806 log << tcu::TestLog::Message << "Buffer value at index 2 was expected to be 3, but was[" << bufferPtr[2]
1807 << tcu::TestLog::EndMessage;
1808 return tcu::TestStatus::fail("Fail");
1809 }
1810 }
1811
1812 if (m_params.geomShader)
1813 {
1814 if (bufferPtr[3] != 4u)
1815 {
1816 log << tcu::TestLog::Message << "Buffer value at index 3 was expected to be 4, but was[" << bufferPtr[3]
1817 << tcu::TestLog::EndMessage;
1818 return tcu::TestStatus::fail("Fail");
1819 }
1820 }
1821
1822 if (m_params.fragShader && !m_params.rasterizerDiscardEnable)
1823 {
1824 bool usesSrcOneDstOneBlending =
1825 (!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable) ||
1826 hasDynamicState(getDynamicStates(), vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT);
1827
1828 for (int32_t j = 0; j < height; ++j)
1829 {
1830 for (int32_t i = 0; i < width; ++i)
1831 {
1832 const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
1833
1834 tcu::Vec4 expectedColor = blackColor;
1835 bool inside = isInsidePrimitive(i, j, width, height);
1836 if (m_params.conservativeRasterization && m_params.conservativeRasterizationOverestimate && !inside)
1837 continue;
1838 if (inside && (!m_params.cull || m_params.lines) && (!m_params.colorWrite || m_params.colorWriteEnable))
1839 {
1840 if (!m_params.depthBoundsTestEnable && (!m_params.depthClip || i < 16) &&
1841 !m_params.discardRectanglesEnable)
1842 {
1843 expectedColor = whiteColor;
1844 if (m_params.alphaToOne)
1845 expectedColor.w() = 1.0f;
1846 if (m_params.colorBlendEnable && secondDraw && !m_params.logicOpEnable &&
1847 !m_params.stencilTestEnable)
1848 {
1849 if (usesSrcOneDstOneBlending)
1850 {
1851 // using src_factor=ONE dst_factor=ONE blending from dynamic state
1852 expectedColor = tcu::Vec4(1.0f);
1853 }
1854 // otherwise dst_factor=ZERO, so expect 'whiteColor'
1855 }
1856 }
1857 }
1858
1859 if (deFloatAbs(color.x() - expectedColor.x()) > threshold ||
1860 deFloatAbs(color.y() - expectedColor.y()) > threshold ||
1861 deFloatAbs(color.z() - expectedColor.z()) > threshold ||
1862 deFloatAbs(color.w() - expectedColor.w()) > threshold)
1863 {
1864 log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") is expected to be ("
1865 << expectedColor << "), but was (" << color << ")" << tcu::TestLog::EndMessage;
1866 return tcu::TestStatus::fail("Fail");
1867 }
1868 }
1869 }
1870 }
1871
1872 if (m_params.fragShader && !m_params.rasterizerDiscardEnable)
1873 {
1874 const auto depthBuffer =
1875 readDepthAttachment(vk, device, queue, queueFamilyIndex, alloc, **depthImage, depthStencilAttachmentFormat,
1876 tcu::UVec2(width, height), vk::VK_IMAGE_LAYOUT_GENERAL);
1877 const auto depthAccess = depthBuffer->getAccess();
1878 const auto stencilBuffer = readStencilAttachment(vk, device, queue, queueFamilyIndex, alloc, **depthImage,
1879 depthStencilAttachmentFormat, tcu::UVec2(width, height),
1880 vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1881 const auto stencilAccess = stencilBuffer->getAccess();
1882 const float depthEpsilon = 0.02f;
1883
1884 for (int32_t j = 0; j < height; ++j)
1885 {
1886 for (int32_t i = 0; i < width; ++i)
1887 {
1888 const float depth = depthAccess.getPixDepth(i, j);
1889 const int stencil = stencilAccess.getPixStencil(i, j);
1890 bool inside = isInsidePrimitive(i, j, width, height);
1891 if (m_params.conservativeRasterization && m_params.conservativeRasterizationOverestimate && !inside)
1892 continue;
1893 if (inside && !m_params.depthBoundsTestEnable && !m_params.discardRectanglesEnable &&
1894 (!m_params.cull || m_params.lines))
1895 {
1896 float depthMin = 0.4f - depthEpsilon;
1897 float depthMax = 0.6f + depthEpsilon;
1898 if (m_params.stencilTestEnable)
1899 {
1900 depthMin = 0.7f - depthEpsilon;
1901 depthMax = 0.9f + depthEpsilon;
1902 }
1903 if (m_params.depthClamp)
1904 {
1905 depthMin = 0.35f - depthEpsilon;
1906 depthMax = 0.45f + depthEpsilon;
1907 }
1908 if (m_params.depthClip)
1909 {
1910 depthMin = 0.9f - depthEpsilon;
1911 depthMax = 1.0f + depthEpsilon;
1912 }
1913 if (m_params.depthClipControl)
1914 {
1915 depthMin = 0.7f - depthEpsilon;
1916 depthMax = 1.0f + depthEpsilon;
1917 }
1918 if (m_params.depthBiasEnable)
1919 {
1920 if (m_params.lines)
1921 {
1922 depthMin += 0.004f;
1923 depthMax += 0.004f;
1924 }
1925 else
1926 {
1927 depthMin += 0.03f;
1928 depthMax += 0.03f;
1929 }
1930 }
1931 if (!m_params.depthTestEnable)
1932 {
1933 depthMin = 1.0f - depthEpsilon;
1934 depthMax = 1.0f + depthEpsilon;
1935 }
1936
1937 if (depth < depthMin || depth > depthMax)
1938 {
1939 log << tcu::TestLog::Message << "Depth at (" << i << ", " << j
1940 << ") is expected to be between 0.4f and 0.6f, but was (" << depth << ")"
1941 << tcu::TestLog::EndMessage;
1942 return tcu::TestStatus::fail("Fail");
1943 }
1944 if (m_params.stencilTestEnable && (!m_params.depthClip || i < 16))
1945 {
1946 if (stencil != 255)
1947 {
1948 log << tcu::TestLog::Message << "Stencil at (" << i << ", " << j
1949 << ") is expected to be 255, but was (" << stencil << ")" << tcu::TestLog::EndMessage;
1950 return tcu::TestStatus::fail("Fail");
1951 }
1952 }
1953 }
1954 else
1955 {
1956 if (deFloatAbs(depth - 1.0f) > depthEpsilon)
1957 {
1958 log << tcu::TestLog::Message << "Depth at (" << i << ", " << j
1959 << ") is expected to be 1.0f, but was (" << depth << ")" << tcu::TestLog::EndMessage;
1960 return tcu::TestStatus::fail("Fail");
1961 }
1962 if (m_params.stencilTestEnable)
1963 {
1964 if (stencil != 0)
1965 {
1966 log << tcu::TestLog::Message << "Stencil at (" << i << ", " << j
1967 << ") is expected to be 0, but was (" << stencil << ")" << tcu::TestLog::EndMessage;
1968 return tcu::TestStatus::fail("Fail");
1969 }
1970 }
1971 }
1972 }
1973 }
1974 }
1975
1976 if (m_params.meshShader)
1977 {
1978 if (bufferPtr[4] != 5u)
1979 {
1980 log << tcu::TestLog::Message << "Buffer value at index 5 was expected to be 6, but was[" << bufferPtr[5]
1981 << tcu::TestLog::EndMessage;
1982 return tcu::TestStatus::fail("Fail");
1983 }
1984 }
1985
1986 return tcu::TestStatus::pass("Pass");
1987 }
1988
1989 class ShaderObjectStateCase : public vkt::TestCase
1990 {
1991 public:
ShaderObjectStateCase(tcu::TestContext & testCtx,const std::string & name,const StateTestParams & testParams)1992 ShaderObjectStateCase(tcu::TestContext &testCtx, const std::string &name, const StateTestParams &testParams)
1993 : vkt::TestCase(testCtx, name)
1994 , m_params(testParams)
1995 {
1996 }
~ShaderObjectStateCase(void)1997 virtual ~ShaderObjectStateCase(void)
1998 {
1999 }
2000
2001 void checkSupport(vkt::Context &context) const override;
2002 virtual void initPrograms(vk::SourceCollections &programCollection) const override;
createInstance(Context & context) const2003 TestInstance *createInstance(Context &context) const override
2004 {
2005 return new ShaderObjectStateInstance(context, m_params);
2006 }
2007
2008 const StateTestParams m_params;
2009 };
2010
checkSupport(Context & context) const2011 void ShaderObjectStateCase::checkSupport(Context &context) const
2012 {
2013 const auto &edsFeatures = context.getExtendedDynamicStateFeaturesEXT();
2014 const auto &eds2Features = context.getExtendedDynamicState2FeaturesEXT();
2015 const auto &eds3Features = context.getExtendedDynamicState3FeaturesEXT();
2016
2017 const auto &vki = context.getInstanceInterface();
2018 const auto physicalDevice = context.getPhysicalDevice();
2019 if (findDSFormat(vki, physicalDevice) == vk::VK_FORMAT_UNDEFINED)
2020 TCU_THROW(NotSupportedError, "Required depth/stencil format not supported");
2021
2022 if (!m_params.pipeline)
2023 context.requireDeviceFunctionality("VK_EXT_shader_object");
2024 else
2025 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
2026
2027 if (m_params.logicOp)
2028 {
2029 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LOGIC_OP);
2030 if (m_params.pipeline && !eds2Features.extendedDynamicState2LogicOp)
2031 TCU_THROW(NotSupportedError, "extendedDynamicState2LogicOp not supported");
2032 }
2033 if (m_params.alphaToOne)
2034 {
2035 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_ALPHA_TO_ONE);
2036 if (m_params.pipeline && !eds3Features.extendedDynamicState3AlphaToOneEnable)
2037 TCU_THROW(NotSupportedError, "extendedDynamicState3AlphaToOneEnable not supported");
2038 }
2039 if (m_params.depthBounds)
2040 {
2041 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_BOUNDS);
2042 if (m_params.pipeline && !edsFeatures.extendedDynamicState)
2043 TCU_THROW(NotSupportedError, "extendedDynamicState not supported");
2044 }
2045 if (m_params.depthClamp)
2046 {
2047 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_CLAMP);
2048 if (m_params.pipeline && !eds3Features.extendedDynamicState3DepthClampEnable)
2049 TCU_THROW(NotSupportedError, "extendedDynamicState3DepthClampEnable not supported");
2050 }
2051 if (m_params.depthClip)
2052 {
2053 context.requireDeviceFunctionality("VK_EXT_depth_clip_enable");
2054 if (!context.getDepthClipEnableFeaturesEXT().depthClipEnable)
2055 TCU_THROW(NotSupportedError, "depthClipEnable not supported");
2056 if (m_params.pipeline && !eds3Features.extendedDynamicState3DepthClipEnable)
2057 TCU_THROW(NotSupportedError, "extendedDynamicState3DepthClipEnable not supported");
2058 }
2059 if (m_params.depthClipControl)
2060 {
2061 context.requireDeviceFunctionality("VK_EXT_depth_clip_control");
2062 if (!context.getDepthClipControlFeaturesEXT().depthClipControl)
2063 TCU_THROW(NotSupportedError, "depthClipControl not supported");
2064 if (m_params.pipeline && !eds3Features.extendedDynamicState3DepthClipNegativeOneToOne)
2065 TCU_THROW(NotSupportedError, "extendedDynamicState3DepthClipNegativeOneToOne not supported");
2066 }
2067 if (m_params.colorWrite)
2068 {
2069 context.requireDeviceFunctionality("VK_EXT_color_write_enable");
2070 if (!context.getColorWriteEnableFeaturesEXT().colorWriteEnable)
2071 TCU_THROW(NotSupportedError, "colorWriteEnable not supported");
2072 }
2073 if (m_params.geometryStreams)
2074 {
2075 context.requireDeviceFunctionality("VK_EXT_transform_feedback");
2076 if (!context.getTransformFeedbackFeaturesEXT().geometryStreams)
2077 TCU_THROW(NotSupportedError, "geometryStreams not supported");
2078 if (m_params.pipeline && !eds3Features.extendedDynamicState3RasterizationStream)
2079 TCU_THROW(NotSupportedError, "extendedDynamicState3RasterizationStream not supported");
2080 }
2081 if (m_params.discardRectangles)
2082 {
2083 context.requireDeviceFunctionality("VK_EXT_discard_rectangles");
2084
2085 uint32_t propertyCount = 0u;
2086 std::vector<vk::VkExtensionProperties> extensionsProperties;
2087 context.getInstanceInterface().enumerateDeviceExtensionProperties(context.getPhysicalDevice(), DE_NULL,
2088 &propertyCount, DE_NULL);
2089 extensionsProperties.resize(propertyCount);
2090 context.getInstanceInterface().enumerateDeviceExtensionProperties(context.getPhysicalDevice(), DE_NULL,
2091 &propertyCount, extensionsProperties.data());
2092
2093 for (const auto &extProp : extensionsProperties)
2094 {
2095 if (strcmp(extProp.extensionName, "VK_EXT_discard_rectangles") == 0)
2096 {
2097 if (extProp.specVersion < 2)
2098 TCU_THROW(NotSupportedError, "VK_EXT_discard_rectangles is version 1. Needs version 2 or higher");
2099 }
2100 }
2101 }
2102 if (m_params.conservativeRasterization)
2103 {
2104 context.requireDeviceFunctionality("VK_EXT_conservative_rasterization");
2105 if (m_params.pipeline && !eds3Features.extendedDynamicState3ConservativeRasterizationMode)
2106 TCU_THROW(NotSupportedError, "extendedDynamicState3ConservativeRasterizationMode not supported");
2107 }
2108 if (m_params.sampleLocations)
2109 {
2110 context.requireDeviceFunctionality("VK_EXT_sample_locations");
2111 if (m_params.sampleLocationsEnable &&
2112 (context.getSampleLocationsPropertiesEXT().sampleLocationSampleCounts & vk::VK_SAMPLE_COUNT_1_BIT) == 0)
2113 TCU_THROW(NotSupportedError, "VK_SAMPLE_COUNT_1_BIT not supported in sampleLocationSampleCounts");
2114 }
2115 if (m_params.provokingVertex)
2116 {
2117 context.requireDeviceFunctionality("VK_EXT_provoking_vertex");
2118 if (m_params.pipeline && !eds3Features.extendedDynamicState3ProvokingVertexMode)
2119 TCU_THROW(NotSupportedError, "extendedDynamicState3ProvokingVertexMode not supported");
2120 }
2121 if (m_params.lineRasterization)
2122 {
2123 if (!context.isDeviceFunctionalitySupported("VK_KHR_line_rasterization") &&
2124 !context.isDeviceFunctionalitySupported("VK_EXT_line_rasterization"))
2125 TCU_THROW(NotSupportedError, "VK_KHR_line_rasterization and VK_EXT_line_rasterization are not supported");
2126 if (!context.getLineRasterizationFeatures().rectangularLines)
2127 TCU_THROW(NotSupportedError, "rectangularLines not supported");
2128 if (m_params.pipeline && !eds3Features.extendedDynamicState3LineRasterizationMode)
2129 TCU_THROW(NotSupportedError, "extendedDynamicState3LineRasterizationMode not supported");
2130 if (m_params.pipeline && !eds3Features.extendedDynamicState3LineStippleEnable)
2131 TCU_THROW(NotSupportedError, "extendedDynamicState3LineStippleEnable not supported");
2132 if (m_params.stippledLineEnable && !context.getLineRasterizationFeatures().stippledRectangularLines)
2133 TCU_THROW(NotSupportedError, "stippledRectangularLines not supported");
2134 }
2135 if (m_params.geomShader)
2136 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
2137 if (m_params.tessShader)
2138 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
2139 if (m_params.meshShader)
2140 {
2141 context.requireDeviceFunctionality("VK_EXT_mesh_shader");
2142 if (!context.getMeshShaderFeaturesEXT().meshShader)
2143 TCU_THROW(NotSupportedError, "Mesh shaders not supported");
2144 }
2145 if (m_params.lines)
2146 {
2147 if (m_params.pipeline && !edsFeatures.extendedDynamicState)
2148 TCU_THROW(NotSupportedError, "extendedDynamicState not supported");
2149 }
2150 if (m_params.colorBlendEnable && m_params.pipeline)
2151 {
2152 context.requireDeviceFunctionality("VK_EXT_extended_dynamic_state3");
2153 if (!eds3Features.extendedDynamicState3ColorBlendEnable)
2154 TCU_THROW(NotSupportedError, "extendedDynamicState3ColorBlendEnable not supported");
2155 }
2156 }
2157
initPrograms(vk::SourceCollections & programCollection) const2158 void ShaderObjectStateCase::initPrograms(vk::SourceCollections &programCollection) const
2159 {
2160 std::stringstream vert;
2161 std::stringstream geom;
2162 std::stringstream tesc;
2163 std::stringstream tese;
2164 std::stringstream frag;
2165
2166 vert << "#version 450\n"
2167 << "layout(binding = 0) buffer Output {\n"
2168 << " uint values[8];\n"
2169 << "} buffer_out;\n\n"
2170 << "void main() {\n"
2171 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1)) - vec2(0.0001f);\n";
2172 if (m_params.depthClip)
2173 vert << " float z = 0.9f;\n";
2174 else
2175 vert << " float z = 0.7f;\n";
2176 vert << " if ((gl_VertexIndex & 1) > 0)\n"
2177 << " z += 0.2f;\n"
2178 << " if ((gl_InstanceIndex & 1) > 0)\n"
2179 << " z -= 0.3f;\n"
2180 << " gl_Position = vec4(pos - 0.5f, z, 1.0f);\n"
2181 << " if (gl_VertexIndex == 0)\n"
2182 << " buffer_out.values[0] = 1u;\n"
2183 << "}\n";
2184
2185 tesc << "#version 450\n"
2186 << "layout(vertices = 4) out;\n"
2187 << "layout(binding = 0) buffer Output {\n"
2188 << " uint values[8];\n"
2189 << "} buffer_out;\n\n"
2190 << "void main (void)\n"
2191 << "{\n"
2192 << " if (gl_InvocationID == 0) {\n"
2193 << " gl_TessLevelInner[0] = 1.0;\n"
2194 << " gl_TessLevelInner[1] = 1.0;\n"
2195 << " gl_TessLevelOuter[0] = 1.0;\n"
2196 << " gl_TessLevelOuter[1] = 1.0;\n"
2197 << " gl_TessLevelOuter[2] = 1.0;\n"
2198 << " gl_TessLevelOuter[3] = 1.0;\n"
2199 << " buffer_out.values[1] = 2u;\n"
2200 << " }\n"
2201 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
2202 << "}\n";
2203
2204 tese << "#version 450\n";
2205 if (m_params.lines)
2206 tese << "layout(isolines, equal_spacing) in;\n";
2207 else
2208 tese << "layout(quads, equal_spacing) in;\n";
2209 tese << "layout(binding = 0) buffer Output {\n"
2210 << " uint values[8];\n"
2211 << "} buffer_out;\n\n"
2212 << "void main (void)\n"
2213 << "{\n"
2214 << " float u = gl_TessCoord.x;\n"
2215 << " float v = gl_TessCoord.y;\n"
2216 << " float omu = 1.0f - u;\n"
2217 << " float omv = 1.0f - v;\n"
2218 << " gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * "
2219 "gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
2220 << " gl_Position.x *= 1.5f;\n"
2221 << " if (gl_PrimitiveID == 0u)\n"
2222 << " buffer_out.values[2] = 3u;\n"
2223 << "}\n";
2224
2225 geom << "#version 450\n";
2226 if (m_params.lines)
2227 geom << "layout(lines) in;\n";
2228 else
2229 geom << "layout(triangles) in;\n";
2230 if (m_params.lines)
2231 geom << "layout(line_strip, max_vertices = 4) out;\n";
2232 else
2233 geom << "layout(triangle_strip, max_vertices = 4) out;\n";
2234 if (m_params.geometryStreams)
2235 geom << "layout(stream = 0, xfb_buffer = 0, xfb_offset = 0, xfb_stride = 16, location = 0) out vec4 out0;\n";
2236 geom << "layout(binding = 0) buffer Output {\n"
2237 << " uint values[8];\n"
2238 << "} buffer_out;\n\n"
2239 << "void main(void)\n"
2240 << "{\n"
2241 << " gl_Position = gl_in[0].gl_Position;\n"
2242 << " gl_Position.y *= 1.5f;\n";
2243 if (m_params.geometryStreams)
2244 geom << " out0 = vec4(1.0f);\n"
2245 << " EmitStreamVertex(0);\n";
2246 else
2247 geom << " EmitVertex();\n";
2248 geom << " gl_Position = gl_in[1].gl_Position;\n"
2249 << " gl_Position.y *= 1.5f;\n";
2250 if (m_params.geometryStreams)
2251 geom << " out0 = vec4(2.0f);\n"
2252 << " EmitStreamVertex(0);\n";
2253 else
2254 geom << " EmitVertex();\n";
2255 if (!m_params.lines)
2256 {
2257 geom << " gl_Position = gl_in[2].gl_Position;\n"
2258 << " gl_Position.y *= 1.5f;\n";
2259 if (m_params.geometryStreams)
2260 geom << " out0 = vec4(3.0f);\n"
2261 << " EmitStreamVertex(0);\n";
2262 else
2263 geom << " EmitVertex();\n";
2264 }
2265 if (m_params.geometryStreams)
2266 geom << " EndStreamPrimitive(0);\n";
2267 else
2268 geom << " EndPrimitive();\n";
2269 geom << " buffer_out.values[3] = 4u;\n";
2270 geom << "}\n";
2271
2272 frag << "#version 450\n"
2273 << "layout (location=0) out vec4 outColor;\n"
2274 << "void main() {\n"
2275 << " outColor = vec4(0.75f);\n"
2276 << "}\n";
2277
2278 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
2279 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
2280 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
2281 programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
2282 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
2283
2284 if (m_params.meshShader)
2285 {
2286 std::stringstream mesh;
2287
2288 mesh << "#version 460\n"
2289 << "#extension GL_EXT_mesh_shader : require\n"
2290 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
2291 << "layout(max_vertices = 4) out;\n"
2292 << "layout(max_primitives = 2) out;\n";
2293 if (m_params.lines)
2294 mesh << "layout(lines) out;\n";
2295 else
2296 mesh << "layout(triangles) out;\n";
2297 mesh << "layout(binding = 0) buffer Output {\n"
2298 << " uint values[8];\n"
2299 << "} buffer_out;\n\n"
2300 << "void main() {\n"
2301 << " SetMeshOutputsEXT(4u, 2u);\n";
2302 if (m_params.depthClip)
2303 mesh << " float z = 0.9f;\n";
2304 else
2305 mesh << " float z = 0.7f;\n";
2306 mesh << " if (gl_GlobalInvocationID.x == 1) z -= 0.3f;\n"
2307 << " gl_MeshVerticesEXT[0].gl_Position = vec4(-0.5f, -0.5f, z, 1.0f);\n"
2308 << " gl_MeshVerticesEXT[1].gl_Position = vec4(-0.5f, 0.5f, z, 1.0f);\n"
2309 << " gl_MeshVerticesEXT[2].gl_Position = vec4(0.5f, -0.5f, z + 0.2f, 1.0f);\n"
2310 << " gl_MeshVerticesEXT[3].gl_Position = vec4(0.5f, 0.5f, z + 0.2f, 1.0f);\n";
2311 if (m_params.lines)
2312 mesh << " gl_PrimitiveLineIndicesEXT[0] = uvec2(0u, 2u);\n"
2313 << " gl_PrimitiveLineIndicesEXT[1] = uvec2(1u, 3u);\n";
2314 else
2315 mesh << " gl_PrimitiveTriangleIndicesEXT[0] = uvec3(0u, 1u, 2u);\n"
2316 << " gl_PrimitiveTriangleIndicesEXT[1] = uvec3(1u, 3u, 2u);\n";
2317 mesh << " buffer_out.values[4] = 5u;\n"
2318 << "}\n";
2319
2320 programCollection.glslSources.add("mesh")
2321 << glu::MeshSource(mesh.str())
2322 << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
2323 }
2324 }
2325
2326 struct UnusedBuiltinParams
2327 {
2328 bool linked;
2329 vk::VkShaderStageFlagBits stage;
2330 bool builtin;
2331 };
2332
2333 enum TessellationSpacing
2334 {
2335 EQUAL,
2336 EVEN,
2337 ODD,
2338 };
2339
2340 struct TessellationModesParams
2341 {
2342 uint32_t subdivision;
2343 TessellationSpacing spacing;
2344 };
2345
2346 class ShaderObjectUnusedBuiltinInstance : public vkt::TestInstance
2347 {
2348 public:
ShaderObjectUnusedBuiltinInstance(Context & context,const UnusedBuiltinParams & params)2349 ShaderObjectUnusedBuiltinInstance(Context &context, const UnusedBuiltinParams ¶ms)
2350 : vkt::TestInstance(context)
2351 , m_params(params)
2352 {
2353 }
~ShaderObjectUnusedBuiltinInstance(void)2354 virtual ~ShaderObjectUnusedBuiltinInstance(void)
2355 {
2356 }
2357
2358 tcu::TestStatus iterate(void) override;
2359
2360 private:
2361 UnusedBuiltinParams m_params;
2362 };
2363
iterate(void)2364 tcu::TestStatus ShaderObjectUnusedBuiltinInstance::iterate(void)
2365 {
2366 const vk::VkInstance instance = m_context.getInstance();
2367 const vk::InstanceDriver instanceDriver(m_context.getPlatformInterface(), instance);
2368 const vk::DeviceInterface &vk = m_context.getDeviceInterface();
2369 const vk::VkDevice device = m_context.getDevice();
2370 const vk::VkQueue queue = m_context.getUniversalQueue();
2371 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2372 auto &alloc = m_context.getDefaultAllocator();
2373 tcu::TestLog &log = m_context.getTestContext().getLog();
2374 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(
2375 m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
2376 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
2377 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
2378 const bool taskSupported = m_context.getMeshShaderFeatures().taskShader;
2379 const bool meshSupported = m_context.getMeshShaderFeatures().meshShader;
2380
2381 vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
2382 const auto subresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2383 const auto subresourceLayers = vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
2384 const vk::VkRect2D renderArea = vk::makeRect2D(0, 0, 32, 32);
2385 vk::VkExtent3D extent = {renderArea.extent.width, renderArea.extent.height, 1};
2386
2387 const vk::VkImageCreateInfo createInfo = {
2388 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
2389 DE_NULL, // const void* pNext
2390 0u, // VkImageCreateFlags flags
2391 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
2392 colorAttachmentFormat, // VkFormat format
2393 {32, 32, 1}, // VkExtent3D extent
2394 1u, // uint32_t mipLevels
2395 1u, // uint32_t arrayLayers
2396 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
2397 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
2398 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
2399 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
2400 0, // uint32_t queueFamilyIndexCount
2401 DE_NULL, // const uint32_t* pQueueFamilyIndices
2402 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
2403 };
2404
2405 de::MovePtr<vk::ImageWithMemory> image = de::MovePtr<vk::ImageWithMemory>(
2406 new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
2407 const auto imageView =
2408 vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
2409
2410 const vk::VkDeviceSize colorOutputBufferSize =
2411 renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
2412 de::MovePtr<vk::BufferWithMemory> colorOutputBuffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
2413 vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT),
2414 vk::MemoryRequirement::HostVisible));
2415
2416 const auto &binaries = m_context.getBinaryCollection();
2417 vk::VkShaderEXT shaders[5];
2418
2419 vk::VkShaderCreateInfoEXT shaderCreateInfos[5]{
2420 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("vert"), tessellationSupported,
2421 geometrySupported),
2422 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, binaries.get("tesc"),
2423 tessellationSupported, geometrySupported),
2424 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, binaries.get("tese"),
2425 tessellationSupported, geometrySupported),
2426 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_GEOMETRY_BIT, binaries.get("geom"), tessellationSupported,
2427 geometrySupported),
2428 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("frag"), tessellationSupported,
2429 geometrySupported),
2430 };
2431
2432 vk.createShadersEXT(device, 5u, shaderCreateInfos, DE_NULL, shaders);
2433
2434 if (m_params.linked)
2435 for (auto &ci : shaderCreateInfos)
2436 ci.flags |= vk::VK_SHADER_CREATE_LINK_STAGE_BIT_EXT;
2437
2438 const vk::Move<vk::VkCommandPool> cmdPool(vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
2439 const vk::Move<vk::VkCommandBuffer> cmdBuffer(
2440 allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2441
2442 vk::beginCommandBuffer(vk, *cmdBuffer);
2443
2444 vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(
2445 vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
2446 vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
2447 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2448 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u,
2449 (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
2450 &preImageBarrier);
2451
2452 const vk::VkClearValue clearValue = vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 0.0f});
2453 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL,
2454 vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
2455
2456 vk::bindGraphicsShaders(vk, *cmdBuffer, shaders[0], shaders[1], shaders[2], shaders[3], shaders[4], taskSupported,
2457 meshSupported);
2458 vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
2459
2460 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
2461
2462 vk::endRendering(vk, *cmdBuffer);
2463
2464 vk::VkImageMemoryBarrier postImageBarrier =
2465 vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT,
2466 vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
2467 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2468 vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u,
2469 (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
2470 &postImageBarrier);
2471
2472 const vk::VkBufferImageCopy copyRegion = vk::makeBufferImageCopy(extent, subresourceLayers);
2473 vk.cmdCopyImageToBuffer(*cmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u, ©Region);
2474
2475 vk::endCommandBuffer(vk, *cmdBuffer);
2476 vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
2477
2478 for (uint32_t i = 0u; i < 5u; ++i)
2479 vk.destroyShaderEXT(device, shaders[i], DE_NULL);
2480
2481 tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(
2482 vk::mapVkFormat(colorAttachmentFormat), renderArea.extent.width, renderArea.extent.height, 1,
2483 (const void *)colorOutputBuffer->getAllocation().getHostPtr());
2484
2485 const tcu::Vec4 black = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
2486 const tcu::Vec4 white = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
2487 const uint32_t width = resultBuffer.getWidth();
2488 const uint32_t height = resultBuffer.getHeight();
2489 const uint32_t xOffset = 4u;
2490 const uint32_t yOffset = 4u;
2491
2492 for (uint32_t j = 0; j < height; ++j)
2493 {
2494 for (uint32_t i = 0; i < width; ++i)
2495 {
2496 const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
2497 if (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset)
2498 {
2499 if (color != white)
2500 {
2501 log << tcu::TestLog::Message << "Color at (" << i << ", " << j
2502 << ") is expected to be (1.0, 1.0, 1.0, 1.0), but was (" << color << ")"
2503 << tcu::TestLog::EndMessage;
2504 return tcu::TestStatus::fail("Fail");
2505 }
2506 }
2507 else
2508 {
2509 if (color != black)
2510 {
2511 log << tcu::TestLog::Message << "Color at (" << i << ", " << j
2512 << ") is expected to be (0.0, 0.0, 0.0, 0.0), but was (" << color << ")"
2513 << tcu::TestLog::EndMessage;
2514 return tcu::TestStatus::fail("Fail");
2515 }
2516 }
2517 }
2518 }
2519
2520 return tcu::TestStatus::pass("Pass");
2521 }
2522
2523 class ShaderObjectUnusedBuiltinCase : public vkt::TestCase
2524 {
2525 public:
ShaderObjectUnusedBuiltinCase(tcu::TestContext & testCtx,const std::string & name,const UnusedBuiltinParams & testParams)2526 ShaderObjectUnusedBuiltinCase(tcu::TestContext &testCtx, const std::string &name,
2527 const UnusedBuiltinParams &testParams)
2528 : vkt::TestCase(testCtx, name)
2529 , m_params(testParams)
2530 {
2531 }
~ShaderObjectUnusedBuiltinCase(void)2532 virtual ~ShaderObjectUnusedBuiltinCase(void)
2533 {
2534 }
2535
2536 void checkSupport(vkt::Context &context) const override;
2537 virtual void initPrograms(vk::SourceCollections &programCollection) const override;
createInstance(Context & context) const2538 TestInstance *createInstance(Context &context) const override
2539 {
2540 return new ShaderObjectUnusedBuiltinInstance(context, m_params);
2541 }
2542
2543 private:
2544 const UnusedBuiltinParams m_params;
2545 };
2546
checkSupport(vkt::Context & context) const2547 void ShaderObjectUnusedBuiltinCase::checkSupport(vkt::Context &context) const
2548 {
2549 context.requireDeviceFunctionality("VK_EXT_shader_object");
2550 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
2551 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
2552 }
2553
initPrograms(vk::SourceCollections & programCollection) const2554 void ShaderObjectUnusedBuiltinCase::initPrograms(vk::SourceCollections &programCollection) const
2555 {
2556 std::stringstream vert;
2557 std::stringstream geom;
2558 std::stringstream tesc;
2559 std::stringstream tese;
2560 std::stringstream frag;
2561
2562 vert << "#version 450\n";
2563 if (m_params.stage == vk::VK_SHADER_STAGE_VERTEX_BIT && !m_params.builtin)
2564 vert << "layout(location = 0) out vec4 unused;\n";
2565 vert << "void main() {\n"
2566 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
2567 << " gl_Position = vec4(pos - 0.5f, 0.0f, 1.0f);\n";
2568 if (m_params.stage == vk::VK_SHADER_STAGE_VERTEX_BIT)
2569 {
2570 if (m_params.builtin)
2571 {
2572 vert << " gl_PointSize = 16.0f;\n";
2573 vert << " gl_ClipDistance[0] = 2.0f;\n";
2574 }
2575 else
2576 {
2577 vert << " unused = vec4(1.0f);\n";
2578 }
2579 }
2580 vert << "}\n";
2581
2582 tesc << "#version 450\n"
2583 << "\n"
2584 << "layout(vertices = 4) out;\n";
2585 if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT && !m_params.builtin)
2586 tesc << "layout(location = 0) out vec4 unused[];\n";
2587 tesc << "\n"
2588 << "void main (void)\n"
2589 << "{\n"
2590 << " if (gl_InvocationID == 0) {\n"
2591 << " gl_TessLevelInner[0] = 1.0;\n"
2592 << " gl_TessLevelInner[1] = 1.0;\n"
2593 << " gl_TessLevelOuter[0] = 1.0;\n"
2594 << " gl_TessLevelOuter[1] = 1.0;\n"
2595 << " gl_TessLevelOuter[2] = 1.0;\n"
2596 << " gl_TessLevelOuter[3] = 1.0;\n"
2597 << " }\n"
2598 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n";
2599 if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2600 {
2601 if (m_params.builtin)
2602 {
2603 tesc << " gl_out[gl_InvocationID].gl_PointSize = 16.0f;\n";
2604 tesc << " gl_out[gl_InvocationID].gl_ClipDistance[0] = 2.0f;\n";
2605 }
2606 else
2607 {
2608 tesc << " unused[gl_InvocationID] = vec4(1.0f);\n";
2609 }
2610 }
2611 tesc << "}\n";
2612
2613 tese << "#version 450\n"
2614 << "\n"
2615 << "layout(quads, equal_spacing) in;\n";
2616 if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT && !m_params.builtin)
2617 tese << "layout(location = 0) out vec4 unused;\n";
2618 tese << "\n"
2619 << "void main (void)\n"
2620 << "{\n"
2621 << " float u = gl_TessCoord.x;\n"
2622 << " float v = gl_TessCoord.y;\n"
2623 << " float omu = 1.0f - u;\n"
2624 << " float omv = 1.0f - v;\n"
2625 << " gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * "
2626 "gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
2627 << " gl_Position.x *= 1.5f;\n";
2628 if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2629 {
2630 if (m_params.builtin)
2631 {
2632 tese << " gl_PointSize = 16.0f;\n";
2633 tese << " gl_ClipDistance[0] = 2.0f;\n";
2634 }
2635 else
2636 {
2637 tese << " unused = vec4(1.0f);\n";
2638 }
2639 }
2640 tese << "}\n";
2641
2642 geom << "#version 450\n"
2643 << "layout(triangles) in;\n"
2644 << "layout(triangle_strip, max_vertices = 4) out;\n";
2645 if (m_params.stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT && !m_params.builtin)
2646 geom << "layout(location = 0) out vec4 unused;\n";
2647 geom << "\n"
2648 << "void main(void)\n"
2649 << "{\n"
2650 << " gl_Position = gl_in[0].gl_Position;\n"
2651 << " gl_Position.y *= 1.5f;\n"
2652 << " gl_Position.z = 0.5f;\n"
2653 << " EmitVertex();\n"
2654 << " gl_Position = gl_in[1].gl_Position;\n"
2655 << " gl_Position.y *= 1.5f;\n"
2656 << " gl_Position.z = 0.5f;\n"
2657 << " EmitVertex();\n"
2658 << " gl_Position = gl_in[2].gl_Position;\n"
2659 << " gl_Position.y *= 1.5f;\n"
2660 << " gl_Position.z = 0.5f;\n"
2661 << " EmitVertex();\n"
2662 << " EndPrimitive();\n";
2663 if (m_params.stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2664 {
2665 if (m_params.builtin)
2666 geom << " gl_PointSize = 16.0f;\n";
2667 else
2668 geom << " unused = vec4(1.0f);\n";
2669 }
2670 geom << "}\n";
2671
2672 frag << "#version 450\n"
2673 << "layout (location=0) out vec4 outColor;\n"
2674 << "void main() {\n"
2675 << " outColor = vec4(1.0f);\n"
2676 << "}\n";
2677
2678 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
2679 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
2680 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
2681 programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
2682 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
2683 }
2684
2685 class ShaderObjectTessellationModesInstance : public vkt::TestInstance
2686 {
2687 public:
ShaderObjectTessellationModesInstance(Context & context,const TessellationModesParams & params)2688 ShaderObjectTessellationModesInstance(Context &context, const TessellationModesParams ¶ms)
2689 : vkt::TestInstance(context)
2690 , m_params(params)
2691 {
2692 }
~ShaderObjectTessellationModesInstance(void)2693 virtual ~ShaderObjectTessellationModesInstance(void)
2694 {
2695 }
2696
2697 tcu::TestStatus iterate(void) override;
2698
2699 private:
2700 TessellationModesParams m_params;
2701 };
2702
iterate(void)2703 tcu::TestStatus ShaderObjectTessellationModesInstance::iterate(void)
2704 {
2705 const vk::VkInstance instance = m_context.getInstance();
2706 const vk::InstanceDriver instanceDriver(m_context.getPlatformInterface(), instance);
2707 const vk::DeviceInterface &vk = m_context.getDeviceInterface();
2708 const vk::VkDevice device = m_context.getDevice();
2709 const vk::VkQueue queue = m_context.getUniversalQueue();
2710 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2711 auto &alloc = m_context.getDefaultAllocator();
2712 tcu::TestLog &log = m_context.getTestContext().getLog();
2713 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(
2714 m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
2715 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
2716 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
2717 const bool taskSupported = m_context.getMeshShaderFeatures().taskShader;
2718 const bool meshSupported = m_context.getMeshShaderFeatures().meshShader;
2719
2720 vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
2721 const auto subresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2722 const auto subresourceLayers = vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
2723 const vk::VkRect2D renderArea = vk::makeRect2D(0, 0, 32, 32);
2724 vk::VkExtent3D extent = {renderArea.extent.width, renderArea.extent.height, 1};
2725
2726 const vk::VkImageCreateInfo createInfo = {
2727 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
2728 DE_NULL, // const void* pNext
2729 0u, // VkImageCreateFlags flags
2730 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
2731 colorAttachmentFormat, // VkFormat format
2732 {32, 32, 1}, // VkExtent3D extent
2733 1u, // uint32_t mipLevels
2734 1u, // uint32_t arrayLayers
2735 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
2736 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
2737 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
2738 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
2739 0, // uint32_t queueFamilyIndexCount
2740 DE_NULL, // const uint32_t* pQueueFamilyIndices
2741 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
2742 };
2743
2744 de::MovePtr<vk::ImageWithMemory> image = de::MovePtr<vk::ImageWithMemory>(
2745 new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
2746 const auto imageView =
2747 vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
2748
2749 const vk::VkDeviceSize colorOutputBufferSize =
2750 renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
2751 de::MovePtr<vk::BufferWithMemory> colorOutputBuffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
2752 vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT),
2753 vk::MemoryRequirement::HostVisible));
2754
2755 const auto &binaries = m_context.getBinaryCollection();
2756 const auto vertShader =
2757 vk::createShader(vk, device,
2758 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("vert"),
2759 tessellationSupported, geometrySupported));
2760 const auto tescShader =
2761 vk::createShader(vk, device,
2762 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, binaries.get("tesc"),
2763 tessellationSupported, geometrySupported));
2764 const auto teseShader =
2765 vk::createShader(vk, device,
2766 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, binaries.get("tese"),
2767 tessellationSupported, geometrySupported));
2768 const auto fragShader =
2769 vk::createShader(vk, device,
2770 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("frag"),
2771 tessellationSupported, geometrySupported));
2772
2773 const vk::Move<vk::VkCommandPool> cmdPool(vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
2774 const vk::Move<vk::VkCommandBuffer> cmdBuffer(
2775 allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2776
2777 vk::beginCommandBuffer(vk, *cmdBuffer);
2778
2779 vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(
2780 vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
2781 vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
2782 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2783 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u,
2784 (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
2785 &preImageBarrier);
2786
2787 const vk::VkClearValue clearValue = vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 0.0f});
2788 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL,
2789 vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
2790
2791 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, *tescShader, *teseShader, VK_NULL_HANDLE, *fragShader,
2792 taskSupported, meshSupported);
2793 vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
2794
2795 vk.cmdSetPolygonModeEXT(*cmdBuffer, vk::VK_POLYGON_MODE_LINE);
2796
2797 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
2798
2799 vk::endRendering(vk, *cmdBuffer);
2800
2801 vk::VkImageMemoryBarrier postImageBarrier =
2802 vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT,
2803 vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
2804 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2805 vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u,
2806 (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
2807 &postImageBarrier);
2808
2809 const vk::VkBufferImageCopy copyRegion = vk::makeBufferImageCopy(extent, subresourceLayers);
2810 vk.cmdCopyImageToBuffer(*cmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u, ©Region);
2811
2812 vk::endCommandBuffer(vk, *cmdBuffer);
2813 vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
2814
2815 tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(
2816 vk::mapVkFormat(colorAttachmentFormat), renderArea.extent.width, renderArea.extent.height, 1,
2817 (const void *)colorOutputBuffer->getAllocation().getHostPtr());
2818
2819 const tcu::Vec4 black = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
2820 const tcu::Vec4 white = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
2821 const uint32_t width = resultBuffer.getWidth();
2822 const uint32_t height = resultBuffer.getHeight();
2823
2824 const bool equal1[17][17] = {
2825 {
2826 0,
2827 1,
2828 1,
2829 1,
2830 1,
2831 1,
2832 1,
2833 1,
2834 1,
2835 1,
2836 1,
2837 1,
2838 1,
2839 1,
2840 1,
2841 1,
2842 1,
2843 },
2844 {
2845 1,
2846 0,
2847 0,
2848 0,
2849 0,
2850 0,
2851 0,
2852 0,
2853 0,
2854 0,
2855 0,
2856 0,
2857 0,
2858 0,
2859 0,
2860 0,
2861 1,
2862 },
2863 {
2864 1,
2865 0,
2866 0,
2867 0,
2868 0,
2869 0,
2870 0,
2871 0,
2872 0,
2873 0,
2874 0,
2875 0,
2876 0,
2877 0,
2878 0,
2879 1,
2880 1,
2881 },
2882 {
2883 1,
2884 0,
2885 0,
2886 0,
2887 0,
2888 0,
2889 0,
2890 0,
2891 0,
2892 0,
2893 0,
2894 0,
2895 0,
2896 0,
2897 1,
2898 0,
2899 1,
2900 },
2901 {
2902 1,
2903 0,
2904 0,
2905 0,
2906 0,
2907 0,
2908 0,
2909 0,
2910 0,
2911 0,
2912 0,
2913 0,
2914 0,
2915 1,
2916 0,
2917 0,
2918 1,
2919 },
2920 {
2921 1,
2922 0,
2923 0,
2924 0,
2925 0,
2926 0,
2927 0,
2928 0,
2929 0,
2930 0,
2931 0,
2932 0,
2933 1,
2934 0,
2935 0,
2936 0,
2937 1,
2938 },
2939 {
2940 1,
2941 0,
2942 0,
2943 0,
2944 0,
2945 0,
2946 0,
2947 0,
2948 0,
2949 0,
2950 0,
2951 1,
2952 0,
2953 0,
2954 0,
2955 0,
2956 1,
2957 },
2958 {
2959 1,
2960 0,
2961 0,
2962 0,
2963 0,
2964 0,
2965 0,
2966 0,
2967 0,
2968 0,
2969 1,
2970 0,
2971 0,
2972 0,
2973 0,
2974 0,
2975 1,
2976 },
2977 {
2978 1,
2979 0,
2980 0,
2981 0,
2982 0,
2983 0,
2984 0,
2985 0,
2986 0,
2987 1,
2988 0,
2989 0,
2990 0,
2991 0,
2992 0,
2993 0,
2994 1,
2995 },
2996 {
2997 1,
2998 0,
2999 0,
3000 0,
3001 0,
3002 0,
3003 0,
3004 0,
3005 1,
3006 0,
3007 0,
3008 0,
3009 0,
3010 0,
3011 0,
3012 0,
3013 1,
3014 },
3015 {
3016 1,
3017 0,
3018 0,
3019 0,
3020 0,
3021 0,
3022 0,
3023 1,
3024 0,
3025 0,
3026 0,
3027 0,
3028 0,
3029 0,
3030 0,
3031 0,
3032 1,
3033 },
3034 {
3035 1,
3036 0,
3037 0,
3038 0,
3039 0,
3040 0,
3041 1,
3042 0,
3043 0,
3044 0,
3045 0,
3046 0,
3047 0,
3048 0,
3049 0,
3050 0,
3051 1,
3052 },
3053 {
3054 1,
3055 0,
3056 0,
3057 0,
3058 0,
3059 1,
3060 0,
3061 0,
3062 0,
3063 0,
3064 0,
3065 0,
3066 0,
3067 0,
3068 0,
3069 0,
3070 1,
3071 },
3072 {
3073 1,
3074 0,
3075 0,
3076 0,
3077 1,
3078 0,
3079 0,
3080 0,
3081 0,
3082 0,
3083 0,
3084 0,
3085 0,
3086 0,
3087 0,
3088 0,
3089 1,
3090 },
3091 {
3092 1,
3093 0,
3094 0,
3095 1,
3096 0,
3097 0,
3098 0,
3099 0,
3100 0,
3101 0,
3102 0,
3103 0,
3104 0,
3105 0,
3106 0,
3107 0,
3108 1,
3109 },
3110 {
3111 1,
3112 0,
3113 1,
3114 0,
3115 0,
3116 0,
3117 0,
3118 0,
3119 0,
3120 0,
3121 0,
3122 0,
3123 0,
3124 0,
3125 0,
3126 0,
3127 1,
3128 },
3129 {
3130 1,
3131 1,
3132 1,
3133 1,
3134 1,
3135 1,
3136 1,
3137 1,
3138 1,
3139 1,
3140 1,
3141 1,
3142 1,
3143 1,
3144 1,
3145 1,
3146 1,
3147 },
3148 };
3149
3150 const bool even1[17][17] = {
3151 {
3152 0,
3153 1,
3154 1,
3155 1,
3156 1,
3157 1,
3158 1,
3159 1,
3160 1,
3161 1,
3162 1,
3163 1,
3164 1,
3165 1,
3166 1,
3167 1,
3168 1,
3169 },
3170 {
3171 1,
3172 1,
3173 0,
3174 0,
3175 0,
3176 0,
3177 0,
3178 0,
3179 1,
3180 0,
3181 0,
3182 0,
3183 0,
3184 0,
3185 0,
3186 0,
3187 1,
3188 },
3189 {
3190 1,
3191 0,
3192 1,
3193 0,
3194 0,
3195 0,
3196 0,
3197 0,
3198 1,
3199 0,
3200 0,
3201 0,
3202 0,
3203 0,
3204 0,
3205 1,
3206 1,
3207 },
3208 {
3209 1,
3210 0,
3211 0,
3212 1,
3213 0,
3214 0,
3215 0,
3216 0,
3217 1,
3218 0,
3219 0,
3220 0,
3221 0,
3222 0,
3223 1,
3224 0,
3225 1,
3226 },
3227 {
3228 1,
3229 0,
3230 0,
3231 0,
3232 1,
3233 0,
3234 0,
3235 0,
3236 1,
3237 0,
3238 0,
3239 0,
3240 0,
3241 1,
3242 0,
3243 0,
3244 1,
3245 },
3246 {
3247 1,
3248 0,
3249 0,
3250 0,
3251 0,
3252 1,
3253 0,
3254 0,
3255 1,
3256 0,
3257 0,
3258 0,
3259 1,
3260 0,
3261 0,
3262 0,
3263 1,
3264 },
3265 {
3266 1,
3267 0,
3268 0,
3269 0,
3270 0,
3271 0,
3272 1,
3273 0,
3274 1,
3275 0,
3276 0,
3277 1,
3278 0,
3279 0,
3280 0,
3281 0,
3282 1,
3283 },
3284 {
3285 1,
3286 0,
3287 0,
3288 0,
3289 0,
3290 0,
3291 0,
3292 1,
3293 1,
3294 0,
3295 1,
3296 0,
3297 0,
3298 0,
3299 0,
3300 0,
3301 1,
3302 },
3303 {
3304 1,
3305 1,
3306 1,
3307 1,
3308 1,
3309 1,
3310 1,
3311 1,
3312 1,
3313 1,
3314 1,
3315 1,
3316 1,
3317 1,
3318 1,
3319 1,
3320 1,
3321 },
3322 {
3323 1,
3324 0,
3325 0,
3326 0,
3327 0,
3328 0,
3329 0,
3330 0,
3331 1,
3332 1,
3333 0,
3334 0,
3335 0,
3336 0,
3337 0,
3338 0,
3339 1,
3340 },
3341 {
3342 1,
3343 0,
3344 0,
3345 0,
3346 0,
3347 0,
3348 0,
3349 1,
3350 1,
3351 0,
3352 1,
3353 0,
3354 0,
3355 0,
3356 0,
3357 0,
3358 1,
3359 },
3360 {
3361 1,
3362 0,
3363 0,
3364 0,
3365 0,
3366 0,
3367 1,
3368 0,
3369 1,
3370 0,
3371 0,
3372 1,
3373 0,
3374 0,
3375 0,
3376 0,
3377 1,
3378 },
3379 {
3380 1,
3381 0,
3382 0,
3383 0,
3384 0,
3385 1,
3386 0,
3387 0,
3388 1,
3389 0,
3390 0,
3391 0,
3392 1,
3393 0,
3394 0,
3395 0,
3396 1,
3397 },
3398 {
3399 1,
3400 0,
3401 0,
3402 0,
3403 1,
3404 0,
3405 0,
3406 0,
3407 1,
3408 0,
3409 0,
3410 0,
3411 0,
3412 1,
3413 0,
3414 0,
3415 1,
3416 },
3417 {
3418 1,
3419 0,
3420 0,
3421 1,
3422 0,
3423 0,
3424 0,
3425 0,
3426 1,
3427 0,
3428 0,
3429 0,
3430 0,
3431 0,
3432 1,
3433 0,
3434 1,
3435 },
3436 {
3437 1,
3438 0,
3439 1,
3440 0,
3441 0,
3442 0,
3443 0,
3444 0,
3445 1,
3446 0,
3447 0,
3448 0,
3449 0,
3450 0,
3451 0,
3452 1,
3453 1,
3454 },
3455 {
3456 1,
3457 1,
3458 1,
3459 1,
3460 1,
3461 1,
3462 1,
3463 1,
3464 1,
3465 1,
3466 1,
3467 1,
3468 1,
3469 1,
3470 1,
3471 1,
3472 1,
3473 },
3474 };
3475
3476 const bool odd2[17][17] = {
3477 {
3478 0,
3479 1,
3480 1,
3481 1,
3482 1,
3483 1,
3484 1,
3485 1,
3486 1,
3487 1,
3488 1,
3489 1,
3490 1,
3491 1,
3492 1,
3493 1,
3494 1,
3495 },
3496 {
3497 1,
3498 1,
3499 0,
3500 1,
3501 0,
3502 0,
3503 0,
3504 0,
3505 0,
3506 0,
3507 1,
3508 1,
3509 1,
3510 1,
3511 1,
3512 0,
3513 1,
3514 },
3515 {
3516 1,
3517 0,
3518 1,
3519 1,
3520 0,
3521 0,
3522 1,
3523 1,
3524 1,
3525 1,
3526 0,
3527 0,
3528 0,
3529 0,
3530 1,
3531 1,
3532 1,
3533 },
3534 {
3535 1,
3536 1,
3537 1,
3538 1,
3539 1,
3540 1,
3541 1,
3542 1,
3543 1,
3544 1,
3545 1,
3546 1,
3547 1,
3548 1,
3549 1,
3550 1,
3551 1,
3552 },
3553 {
3554 1,
3555 1,
3556 0,
3557 1,
3558 0,
3559 0,
3560 0,
3561 0,
3562 0,
3563 0,
3564 0,
3565 0,
3566 0,
3567 1,
3568 1,
3569 0,
3570 1,
3571 },
3572 {
3573 1,
3574 1,
3575 0,
3576 1,
3577 0,
3578 0,
3579 0,
3580 0,
3581 0,
3582 0,
3583 0,
3584 0,
3585 1,
3586 0,
3587 1,
3588 0,
3589 1,
3590 },
3591 {
3592 1,
3593 1,
3594 0,
3595 1,
3596 0,
3597 0,
3598 0,
3599 0,
3600 0,
3601 0,
3602 0,
3603 1,
3604 0,
3605 0,
3606 1,
3607 1,
3608 1,
3609 },
3610 {
3611 1,
3612 1,
3613 0,
3614 1,
3615 0,
3616 0,
3617 0,
3618 0,
3619 0,
3620 0,
3621 1,
3622 0,
3623 0,
3624 0,
3625 1,
3626 1,
3627 1,
3628 },
3629 {
3630 1,
3631 0,
3632 1,
3633 1,
3634 0,
3635 0,
3636 0,
3637 0,
3638 0,
3639 1,
3640 0,
3641 0,
3642 0,
3643 0,
3644 1,
3645 1,
3646 1,
3647 },
3648 {
3649 1,
3650 0,
3651 1,
3652 1,
3653 0,
3654 0,
3655 0,
3656 0,
3657 1,
3658 0,
3659 0,
3660 0,
3661 0,
3662 0,
3663 1,
3664 1,
3665 1,
3666 },
3667 {
3668 1,
3669 0,
3670 1,
3671 1,
3672 0,
3673 0,
3674 0,
3675 1,
3676 0,
3677 0,
3678 0,
3679 0,
3680 0,
3681 0,
3682 1,
3683 0,
3684 1,
3685 },
3686 {
3687 1,
3688 0,
3689 1,
3690 1,
3691 0,
3692 0,
3693 1,
3694 0,
3695 0,
3696 0,
3697 0,
3698 0,
3699 0,
3700 0,
3701 1,
3702 0,
3703 1,
3704 },
3705 {
3706 1,
3707 0,
3708 0,
3709 1,
3710 0,
3711 1,
3712 0,
3713 0,
3714 0,
3715 0,
3716 0,
3717 0,
3718 0,
3719 0,
3720 1,
3721 0,
3722 1,
3723 },
3724 {
3725 1,
3726 0,
3727 0,
3728 1,
3729 1,
3730 0,
3731 0,
3732 0,
3733 0,
3734 0,
3735 0,
3736 0,
3737 0,
3738 0,
3739 1,
3740 0,
3741 1,
3742 },
3743 {
3744 1,
3745 1,
3746 1,
3747 1,
3748 1,
3749 1,
3750 1,
3751 1,
3752 1,
3753 1,
3754 1,
3755 1,
3756 1,
3757 1,
3758 1,
3759 1,
3760 1,
3761 },
3762 {
3763 1,
3764 0,
3765 1,
3766 1,
3767 0,
3768 0,
3769 0,
3770 0,
3771 1,
3772 1,
3773 1,
3774 1,
3775 0,
3776 0,
3777 1,
3778 1,
3779 1,
3780 },
3781 {
3782 1,
3783 1,
3784 1,
3785 1,
3786 1,
3787 1,
3788 1,
3789 1,
3790 1,
3791 1,
3792 1,
3793 1,
3794 1,
3795 1,
3796 1,
3797 1,
3798 1,
3799 },
3800 };
3801
3802 for (uint32_t j = 0; j < height; ++j)
3803 {
3804 for (uint32_t i = 0; i < width; ++i)
3805 {
3806 const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
3807
3808 bool inside = false;
3809 if (i >= 7 && i < 24 && j >= 7 && j < 24)
3810 {
3811 if ((m_params.subdivision == 1 && m_params.spacing == EQUAL) ||
3812 (m_params.subdivision == 1 && m_params.spacing == ODD))
3813 inside |= equal1[j - 7][i - 7];
3814 else if ((m_params.subdivision == 1 && m_params.spacing == EVEN) ||
3815 (m_params.subdivision == 2 && m_params.spacing == EQUAL) ||
3816 (m_params.subdivision == 2 && m_params.spacing == EVEN))
3817 inside |= even1[j - 7][i - 7];
3818 else if (m_params.subdivision == 2 && m_params.spacing == ODD)
3819 inside |= odd2[j - 7][i - 7];
3820 }
3821
3822 if (inside)
3823 {
3824 if (color != white)
3825 {
3826 log << tcu::TestLog::Message << "Color at (" << i << ", " << j
3827 << ") is expected to be (1.0, 1.0, 1.0, 1.0), but was (" << color << ")"
3828 << tcu::TestLog::EndMessage;
3829 return tcu::TestStatus::fail("Fail");
3830 }
3831 }
3832 else
3833 {
3834 if (color != black)
3835 {
3836 log << tcu::TestLog::Message << "Color at (" << i << ", " << j
3837 << ") is expected to be (0.0, 0.0, 0.0, 0.0), but was (" << color << ")"
3838 << tcu::TestLog::EndMessage;
3839 return tcu::TestStatus::fail("Fail");
3840 }
3841 }
3842 }
3843 }
3844
3845 return tcu::TestStatus::pass("Pass");
3846 }
3847
3848 class ShaderObjectTessellationModesCase : public vkt::TestCase
3849 {
3850 public:
ShaderObjectTessellationModesCase(tcu::TestContext & testCtx,const std::string & name,const TessellationModesParams & testParams)3851 ShaderObjectTessellationModesCase(tcu::TestContext &testCtx, const std::string &name,
3852 const TessellationModesParams &testParams)
3853 : vkt::TestCase(testCtx, name)
3854 , m_params(testParams)
3855 {
3856 }
~ShaderObjectTessellationModesCase(void)3857 virtual ~ShaderObjectTessellationModesCase(void)
3858 {
3859 }
3860
3861 void checkSupport(vkt::Context &context) const override;
3862 virtual void initPrograms(vk::SourceCollections &programCollection) const override;
createInstance(Context & context) const3863 TestInstance *createInstance(Context &context) const override
3864 {
3865 return new ShaderObjectTessellationModesInstance(context, m_params);
3866 }
3867
3868 private:
3869 const TessellationModesParams m_params;
3870 };
3871
checkSupport(vkt::Context & context) const3872 void ShaderObjectTessellationModesCase::checkSupport(vkt::Context &context) const
3873 {
3874 context.requireDeviceFunctionality("VK_EXT_shader_object");
3875 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
3876 }
3877
initPrograms(vk::SourceCollections & programCollection) const3878 void ShaderObjectTessellationModesCase::initPrograms(vk::SourceCollections &programCollection) const
3879 {
3880 std::stringstream vert;
3881 std::stringstream tesc;
3882 std::stringstream tese;
3883 std::stringstream frag;
3884
3885 vert << "#version 450\n"
3886 << "void main() {\n"
3887 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
3888 << " gl_Position = vec4(pos - 0.5f, 0.0f, 1.0f);\n"
3889 << "}\n";
3890
3891 tesc << "#version 450\n"
3892 << "\n"
3893 << "layout(vertices = 4) out;\n"
3894 << "\n"
3895 << "void main (void)\n"
3896 << "{\n"
3897 << " if (gl_InvocationID == 0) {\n";
3898 if (m_params.subdivision == 1)
3899 tesc << " float subdivision = 1.0f;\n";
3900 else
3901 tesc << " float subdivision = 2.0f;\n";
3902 tesc << " gl_TessLevelInner[0] = subdivision;\n"
3903 << " gl_TessLevelInner[1] = subdivision;\n"
3904 << " gl_TessLevelOuter[0] = subdivision;\n"
3905 << " gl_TessLevelOuter[1] = subdivision;\n"
3906 << " gl_TessLevelOuter[2] = subdivision;\n"
3907 << " gl_TessLevelOuter[3] = subdivision;\n"
3908 << " }\n"
3909 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
3910 << "}\n";
3911
3912 tese << "#version 450\n"
3913 << "\n";
3914 if (m_params.spacing == EQUAL)
3915 tese << "layout(quads, equal_spacing) in;\n";
3916 else if (m_params.spacing == EVEN)
3917 tese << "layout(quads, fractional_even_spacing) in;\n";
3918 else
3919 tese << "layout(quads, fractional_odd_spacing) in;\n";
3920 tese << "\n"
3921 << "void main (void)\n"
3922 << "{\n"
3923 << " float u = gl_TessCoord.x;\n"
3924 << " float v = gl_TessCoord.y;\n"
3925 << " float omu = 1.0f - u;\n"
3926 << " float omv = 1.0f - v;\n"
3927 << " gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * "
3928 "gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
3929 << "}\n";
3930
3931 frag << "#version 450\n"
3932 << "layout (location=0) out vec4 outColor;\n"
3933 << "void main() {\n"
3934 << " outColor = vec4(1.0f);\n"
3935 << "}\n";
3936 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
3937 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
3938 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
3939 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
3940 }
3941
3942 } // namespace
3943
createShaderObjectMiscTests(tcu::TestContext & testCtx)3944 tcu::TestCaseGroup *createShaderObjectMiscTests(tcu::TestContext &testCtx)
3945 {
3946 de::MovePtr<tcu::TestCaseGroup> miscGroup(new tcu::TestCaseGroup(testCtx, "misc"));
3947
3948 const struct
3949 {
3950 uint32_t stride;
3951 const char *name;
3952 } strideTests[] = {
3953 {
3954 16,
3955 "16",
3956 },
3957 {
3958 32,
3959 "32",
3960 },
3961 {
3962 48,
3963 "48",
3964 },
3965 {
3966 40,
3967 "40",
3968 },
3969 };
3970
3971 for (uint32_t i = 0; i < 2; ++i)
3972 {
3973 bool blend1 = i == 0;
3974 de::MovePtr<tcu::TestCaseGroup> blend1Group(new tcu::TestCaseGroup(testCtx, blend1 ? "on" : "off"));
3975 for (uint32_t j = 0; j < 2; ++j)
3976 {
3977 bool blend2 = j == 0;
3978 de::MovePtr<tcu::TestCaseGroup> blend2Group(new tcu::TestCaseGroup(testCtx, blend2 ? "on" : "off"));
3979 for (uint32_t k = 0; k < 2; ++k)
3980 {
3981 bool vertexInputBefore = k == 0;
3982 de::MovePtr<tcu::TestCaseGroup> vertexInputBeforeGroup(
3983 new tcu::TestCaseGroup(testCtx, vertexInputBefore ? "before" : "after"));
3984 for (uint32_t l = 0; l < 2; ++l)
3985 {
3986 bool vertexBuffersNullStride = l == 0;
3987 de::MovePtr<tcu::TestCaseGroup> vertexBuffersNullStrideGroup(
3988 new tcu::TestCaseGroup(testCtx, vertexBuffersNullStride ? "null" : "non_null"));
3989 for (const auto &strideTest : strideTests)
3990 {
3991 de::MovePtr<tcu::TestCaseGroup> strideGroup(new tcu::TestCaseGroup(testCtx, strideTest.name));
3992 for (uint32_t m = 0; m < 2; ++m)
3993 {
3994 bool destroyDescriptorSetLayout = m == 1;
3995 std::string destroyName = destroyDescriptorSetLayout ? "set" : "destroyed";
3996
3997 TestParams params;
3998 params.blendEnabled[0] = blend1;
3999 params.blendEnabled[1] = blend2;
4000 params.vertexInputBefore = vertexInputBefore;
4001 params.vertexBuffersNullStride = vertexBuffersNullStride;
4002 params.stride = strideTest.stride;
4003 params.destroyDescriptorSetLayout = destroyDescriptorSetLayout;
4004 strideGroup->addChild(new ShaderObjectMiscCase(testCtx, destroyName, params));
4005 }
4006 vertexBuffersNullStrideGroup->addChild(strideGroup.release());
4007 }
4008 vertexInputBeforeGroup->addChild(vertexBuffersNullStrideGroup.release());
4009 }
4010 blend2Group->addChild(vertexInputBeforeGroup.release());
4011 }
4012 blend1Group->addChild(blend2Group.release());
4013 }
4014 miscGroup->addChild(blend1Group.release());
4015 }
4016
4017 const struct
4018 {
4019 bool pipeline;
4020 const char *name;
4021 } pipelineTests[] = {
4022 {false, "shaders"},
4023 {true, "pipeline"},
4024 };
4025
4026 const struct
4027 {
4028 bool meshShader;
4029 bool vertShader;
4030 bool tessShader;
4031 bool geomShader;
4032 bool fragShader;
4033 const char *name;
4034 } shadersTests[] = {
4035 {
4036 false,
4037 true,
4038 false,
4039 false,
4040 false,
4041 "vert",
4042 },
4043 {
4044 false,
4045 true,
4046 false,
4047 false,
4048 true,
4049 "vert_frag",
4050 },
4051 {
4052 false,
4053 true,
4054 true,
4055 false,
4056 true,
4057 "vert_tess_frag",
4058 },
4059 {
4060 false,
4061 true,
4062 false,
4063 true,
4064 true,
4065 "vert_geom_frag",
4066 },
4067 {
4068 false,
4069 true,
4070 true,
4071 true,
4072 true,
4073 "vert_tess_geom_frag",
4074 },
4075 {
4076 true,
4077 false,
4078 false,
4079 false,
4080 true,
4081 "mesh_frag",
4082 },
4083 };
4084
4085 const struct
4086 {
4087 bool alphaToOne;
4088 const char *name;
4089 } alphaToOneTests[] = {
4090 {false, "disabled"},
4091 {true, "enabled"},
4092 };
4093
4094 const struct
4095 {
4096 bool depthTestEnable;
4097 bool depthBounds;
4098 bool depthBoundsTestEnable;
4099 bool depthClamp;
4100 bool depthClip;
4101 bool depthClipControl;
4102 bool depthBiasEnable;
4103 const char *name;
4104 } depthTests[]{
4105 {false, false, false, false, false, false, false, "none"},
4106 {true, true, false, false, false, false, false, "bounds_disabled"},
4107 {true, true, true, false, false, false, false, "bounds_enabled"},
4108 {true, false, false, true, false, false, false, "clamp"},
4109 {true, false, false, false, true, false, false, "clip"},
4110 {true, false, false, false, false, true, false, "clip_control"},
4111 {true, false, false, false, false, false, true, "bias"},
4112 };
4113
4114 const struct
4115 {
4116 bool discardRectangles;
4117 bool discardRectanglesEnabled;
4118 const char *name;
4119 } discardRectanglesTests[] = {
4120 {false, false, "disabled"},
4121 {true, false, "enabled"},
4122 {true, true, "discard"},
4123 };
4124
4125 const struct
4126 {
4127 bool rasterizationDiscardEnable;
4128 const char *name;
4129 } rasterizationDiscardEnableTests[] = {
4130 {false, "disabled"},
4131 {true, "enabled"},
4132 };
4133
4134 const struct
4135 {
4136 bool colorBlendEnable;
4137 const char *name;
4138 } colorBlendTests[] = {
4139 {false, "disabled"},
4140 {true, "enabled"},
4141 };
4142
4143 const struct
4144 {
4145 bool lines;
4146 const char *name;
4147 } primitiveTests[] = {
4148 {false, "triangles"},
4149 {true, "lines"},
4150 };
4151
4152 const struct
4153 {
4154 bool stencilEnable;
4155 const char *name;
4156 } stencilTests[] = {
4157 {false, "disabled"},
4158 {true, "enabled"},
4159 };
4160
4161 const struct
4162 {
4163 bool logicOp;
4164 bool logicOpEnable;
4165 const char *name;
4166 } logicOpTests[] = {
4167 {false, false, "disabled"},
4168 {true, false, "enabled"},
4169 {true, true, "copy"},
4170 };
4171
4172 const struct
4173 {
4174 bool geometryStreams;
4175 const char *name;
4176 } geometryStreamsTests[] = {
4177 {false, "disabled"},
4178 {true, "enabled"},
4179 };
4180
4181 const struct
4182 {
4183 bool provokingVertex;
4184 const char *name;
4185 } provokingVertexTests[] = {
4186 {false, "disabled"},
4187 {true, "enabled"},
4188 };
4189
4190 const struct
4191 {
4192 bool sampleLocations;
4193 bool sampleLocationsEnable;
4194 const char *name;
4195 } sampleLocationsTests[] = {
4196 {false, false, "disabled"},
4197 {true, false, "enabled"},
4198 {true, true, "used"},
4199 };
4200
4201 const struct
4202 {
4203 bool lineRasterization;
4204 bool stippledLineEnable;
4205 const char *name;
4206 } linesTests[] = {
4207 {false, false, "default"},
4208 {true, false, "rectangular"},
4209 {true, true, "rectangular_stippled"},
4210 };
4211
4212 const struct
4213 {
4214 bool cull;
4215 const char *name;
4216 } cullTests[] = {
4217 {false, "none"},
4218 {true, "front_and_back"},
4219 };
4220
4221 const struct
4222 {
4223 bool conservativeRasterization;
4224 bool conservativeRasterizationOverestimate;
4225 const char *name;
4226 } conservativeRasterizationTests[] = {
4227 {false, false, "disabled"},
4228 {true, false, "enabled"},
4229 {true, true, "overestimate"},
4230 };
4231
4232 const struct
4233 {
4234 bool colorWrite;
4235 bool colorWriteEnable;
4236 const char *name;
4237 } colorWriteEnableTests[] = {
4238 {false, false, "disabled"},
4239 {true, false, "false"},
4240 {true, true, "true"},
4241 };
4242
4243 de::MovePtr<tcu::TestCaseGroup> stateGroup(new tcu::TestCaseGroup(testCtx, "state"));
4244 for (const auto &pipelineTest : pipelineTests)
4245 {
4246 de::MovePtr<tcu::TestCaseGroup> pipelineGroup(new tcu::TestCaseGroup(testCtx, pipelineTest.name));
4247 for (const auto shadersTest : shadersTests)
4248 {
4249 de::MovePtr<tcu::TestCaseGroup> shadersGroup(new tcu::TestCaseGroup(testCtx, shadersTest.name));
4250
4251 StateTestParams params;
4252 params.pipeline = pipelineTest.pipeline;
4253 params.meshShader = shadersTest.meshShader;
4254 params.vertShader = shadersTest.vertShader;
4255 params.tessShader = shadersTest.tessShader;
4256 params.geomShader = shadersTest.geomShader;
4257 params.fragShader = shadersTest.fragShader;
4258 params.reset();
4259
4260 de::MovePtr<tcu::TestCaseGroup> alphaToOneGroup(new tcu::TestCaseGroup(testCtx, "alphaToOne"));
4261 for (const auto &alphaToOneTest : alphaToOneTests)
4262 {
4263 params.alphaToOne = alphaToOneTest.alphaToOne;
4264 alphaToOneGroup->addChild(new ShaderObjectStateCase(testCtx, alphaToOneTest.name, params));
4265 }
4266 shadersGroup->addChild(alphaToOneGroup.release());
4267 params.reset();
4268
4269 de::MovePtr<tcu::TestCaseGroup> depthGroup(new tcu::TestCaseGroup(testCtx, "depth"));
4270 for (const auto &depthTest : depthTests)
4271 {
4272 params.depthTestEnable = depthTest.depthTestEnable;
4273 params.depthBounds = depthTest.depthBounds;
4274 params.depthBoundsTestEnable = depthTest.depthBoundsTestEnable;
4275 params.depthClamp = depthTest.depthClamp;
4276 params.depthClip = depthTest.depthClip;
4277 params.depthClipControl = depthTest.depthClipControl;
4278 params.depthBiasEnable = depthTest.depthBiasEnable;
4279 depthGroup->addChild(new ShaderObjectStateCase(testCtx, depthTest.name, params));
4280 }
4281 shadersGroup->addChild(depthGroup.release());
4282 params.reset();
4283
4284 de::MovePtr<tcu::TestCaseGroup> discardRectanglesGroup(
4285 new tcu::TestCaseGroup(testCtx, "discard_rectangles"));
4286 for (const auto &discardRectangles : discardRectanglesTests)
4287 {
4288 params.discardRectangles = discardRectangles.discardRectangles;
4289 params.discardRectanglesEnable = discardRectangles.discardRectanglesEnabled;
4290 discardRectanglesGroup->addChild(new ShaderObjectStateCase(testCtx, discardRectangles.name, params));
4291 }
4292 shadersGroup->addChild(discardRectanglesGroup.release());
4293 params.reset();
4294
4295 de::MovePtr<tcu::TestCaseGroup> rasterizationDiscardEnableGroup(
4296 new tcu::TestCaseGroup(testCtx, "rasterization_discard"));
4297 for (const auto &rasterizationDiscardTest : rasterizationDiscardEnableTests)
4298 {
4299 params.rasterizerDiscardEnable = rasterizationDiscardTest.rasterizationDiscardEnable;
4300 rasterizationDiscardEnableGroup->addChild(
4301 new ShaderObjectStateCase(testCtx, rasterizationDiscardTest.name, params));
4302 }
4303 shadersGroup->addChild(rasterizationDiscardEnableGroup.release());
4304 params.reset();
4305
4306 de::MovePtr<tcu::TestCaseGroup> colorBlendGroup(new tcu::TestCaseGroup(testCtx, "color_blend"));
4307 for (const auto &colorBlendTest : colorBlendTests)
4308 {
4309 params.colorBlendEnable = colorBlendTest.colorBlendEnable;
4310 colorBlendGroup->addChild(new ShaderObjectStateCase(testCtx, colorBlendTest.name, params));
4311 }
4312 shadersGroup->addChild(colorBlendGroup.release());
4313 params.reset();
4314
4315 de::MovePtr<tcu::TestCaseGroup> primitivesGroup(new tcu::TestCaseGroup(testCtx, "primitives"));
4316 for (const auto &primitivesTest : primitiveTests)
4317 {
4318 params.lines = primitivesTest.lines;
4319 primitivesGroup->addChild(new ShaderObjectStateCase(testCtx, primitivesTest.name, params));
4320 }
4321 shadersGroup->addChild(primitivesGroup.release());
4322 params.reset();
4323
4324 de::MovePtr<tcu::TestCaseGroup> stencilGroup(new tcu::TestCaseGroup(testCtx, "stencil"));
4325 for (const auto &stencilTest : stencilTests)
4326 {
4327 params.stencilTestEnable = stencilTest.stencilEnable;
4328 stencilGroup->addChild(new ShaderObjectStateCase(testCtx, stencilTest.name, params));
4329 }
4330 shadersGroup->addChild(stencilGroup.release());
4331 params.reset();
4332
4333 de::MovePtr<tcu::TestCaseGroup> logicOpGroup(new tcu::TestCaseGroup(testCtx, "logic_op"));
4334 for (const auto &logicOpTest : logicOpTests)
4335 {
4336 params.logicOp = logicOpTest.logicOp;
4337 params.logicOpEnable = logicOpTest.logicOpEnable;
4338 logicOpGroup->addChild(new ShaderObjectStateCase(testCtx, logicOpTest.name, params));
4339 }
4340 shadersGroup->addChild(logicOpGroup.release());
4341 params.reset();
4342
4343 if (shadersTest.geomShader)
4344 {
4345 de::MovePtr<tcu::TestCaseGroup> geometryStreamsGroup(
4346 new tcu::TestCaseGroup(testCtx, "geometry_streams"));
4347 for (const auto &geometryStreamsTest : geometryStreamsTests)
4348 {
4349 params.geometryStreams = geometryStreamsTest.geometryStreams;
4350 geometryStreamsGroup->addChild(
4351 new ShaderObjectStateCase(testCtx, geometryStreamsTest.name, params));
4352 }
4353 shadersGroup->addChild(geometryStreamsGroup.release());
4354 params.reset();
4355 }
4356
4357 de::MovePtr<tcu::TestCaseGroup> provokingVertexGroup(new tcu::TestCaseGroup(testCtx, "provoking_vertex"));
4358 for (const auto &provokingVertexTest : provokingVertexTests)
4359 {
4360 params.provokingVertex = provokingVertexTest.provokingVertex;
4361 provokingVertexGroup->addChild(new ShaderObjectStateCase(testCtx, provokingVertexTest.name, params));
4362 }
4363 shadersGroup->addChild(provokingVertexGroup.release());
4364 params.reset();
4365
4366 de::MovePtr<tcu::TestCaseGroup> sampleLocationsGroup(new tcu::TestCaseGroup(testCtx, "sample_locations"));
4367 for (const auto &sampleLocationsTest : sampleLocationsTests)
4368 {
4369 params.sampleLocations = sampleLocationsTest.sampleLocations;
4370 params.sampleLocationsEnable = sampleLocationsTest.sampleLocationsEnable;
4371 sampleLocationsGroup->addChild(new ShaderObjectStateCase(testCtx, sampleLocationsTest.name, params));
4372 }
4373 shadersGroup->addChild(sampleLocationsGroup.release());
4374 params.reset();
4375
4376 de::MovePtr<tcu::TestCaseGroup> linesGroup(new tcu::TestCaseGroup(testCtx, "lines"));
4377 for (const auto &linesTest : linesTests)
4378 {
4379 params.lines = true;
4380 params.stippledLineEnable = linesTest.stippledLineEnable;
4381 params.lineRasterization = linesTest.lineRasterization;
4382 linesGroup->addChild(new ShaderObjectStateCase(testCtx, linesTest.name, params));
4383 }
4384 shadersGroup->addChild(linesGroup.release());
4385 params.reset();
4386
4387 de::MovePtr<tcu::TestCaseGroup> cullGroup(new tcu::TestCaseGroup(testCtx, "cull"));
4388 for (const auto &cullTest : cullTests)
4389 {
4390 params.cull = cullTest.cull;
4391 cullGroup->addChild(new ShaderObjectStateCase(testCtx, cullTest.name, params));
4392 }
4393 shadersGroup->addChild(cullGroup.release());
4394 params.reset();
4395
4396 de::MovePtr<tcu::TestCaseGroup> conservativeRasterizationGroup(
4397 new tcu::TestCaseGroup(testCtx, "conservative_rasterization"));
4398 for (const auto &conservativeRasterizationTest : conservativeRasterizationTests)
4399 {
4400 params.conservativeRasterization = conservativeRasterizationTest.conservativeRasterization;
4401 params.conservativeRasterizationOverestimate =
4402 conservativeRasterizationTest.conservativeRasterizationOverestimate;
4403 conservativeRasterizationGroup->addChild(
4404 new ShaderObjectStateCase(testCtx, conservativeRasterizationTest.name, params));
4405 }
4406 shadersGroup->addChild(conservativeRasterizationGroup.release());
4407 params.reset();
4408
4409 de::MovePtr<tcu::TestCaseGroup> colorWriteGroup(new tcu::TestCaseGroup(testCtx, "color_write"));
4410 for (const auto &colorWriteEnableTest : colorWriteEnableTests)
4411 {
4412 params.colorWrite = colorWriteEnableTest.colorWrite;
4413 params.colorWriteEnable = colorWriteEnableTest.colorWriteEnable;
4414 colorWriteGroup->addChild(new ShaderObjectStateCase(testCtx, colorWriteEnableTest.name, params));
4415 }
4416 shadersGroup->addChild(colorWriteGroup.release());
4417 params.reset();
4418
4419 pipelineGroup->addChild(shadersGroup.release());
4420 }
4421 stateGroup->addChild(pipelineGroup.release());
4422 }
4423 miscGroup->addChild(stateGroup.release());
4424
4425 const struct
4426 {
4427 bool linked;
4428 const char *name;
4429 } linkedTests[] = {
4430 {false, "unlinked"},
4431 {true, "linked"},
4432 };
4433
4434 const struct
4435 {
4436 vk::VkShaderStageFlagBits stage;
4437 const char *name;
4438 } shaderStageTests[] = {
4439 {vk::VK_SHADER_STAGE_VERTEX_BIT, "vert"},
4440 {vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "tesc"},
4441 {vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "tese"},
4442 {vk::VK_SHADER_STAGE_GEOMETRY_BIT, "geom"},
4443 };
4444
4445 const struct
4446 {
4447 bool builtin;
4448 const char *name;
4449 } typeTests[] = {
4450 {false, "output"},
4451 {true, "builtin"},
4452 };
4453
4454 de::MovePtr<tcu::TestCaseGroup> unusedVariableGroup(new tcu::TestCaseGroup(testCtx, "unused_variable"));
4455 for (const auto &linkedTest : linkedTests)
4456 {
4457 de::MovePtr<tcu::TestCaseGroup> linkedGroup(new tcu::TestCaseGroup(testCtx, linkedTest.name));
4458 for (const auto &typeTest : typeTests)
4459 {
4460 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(testCtx, typeTest.name));
4461 for (const auto &shaderStageTest : shaderStageTests)
4462 {
4463 UnusedBuiltinParams params;
4464 params.linked = linkedTest.linked;
4465 params.stage = shaderStageTest.stage;
4466 params.builtin = typeTest.builtin;
4467 typeGroup->addChild(new ShaderObjectUnusedBuiltinCase(testCtx, shaderStageTest.name, params));
4468 }
4469 linkedGroup->addChild(typeGroup.release());
4470 }
4471 unusedVariableGroup->addChild(linkedGroup.release());
4472 }
4473 miscGroup->addChild(unusedVariableGroup.release());
4474
4475 const struct
4476 {
4477 uint32_t subdivision;
4478 const char *name;
4479 } subdivisionTests[] = {
4480 {1, "one"},
4481 {2, "two"},
4482 };
4483
4484 const struct
4485 {
4486 TessellationSpacing spacing;
4487 const char *name;
4488 } spacingTests[] = {
4489 {EQUAL, "equal"},
4490 {EVEN, "even"},
4491 {ODD, "odd"},
4492 };
4493
4494 de::MovePtr<tcu::TestCaseGroup> tessellationModesGroup(new tcu::TestCaseGroup(testCtx, "tessellation_modes"));
4495 for (const auto &subdivisionTest : subdivisionTests)
4496 {
4497 de::MovePtr<tcu::TestCaseGroup> subdivisionGroup(new tcu::TestCaseGroup(testCtx, subdivisionTest.name));
4498
4499 for (const auto &spacingTest : spacingTests)
4500 {
4501 TessellationModesParams params;
4502 params.subdivision = subdivisionTest.subdivision;
4503 params.spacing = spacingTest.spacing;
4504 subdivisionGroup->addChild(new ShaderObjectTessellationModesCase(testCtx, spacingTest.name, params));
4505 }
4506 tessellationModesGroup->addChild(subdivisionGroup.release());
4507 }
4508 miscGroup->addChild(tessellationModesGroup.release());
4509
4510 return miscGroup.release();
4511 }
4512
4513 } // namespace ShaderObject
4514 } // namespace vkt
4515