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 bool blendEnabled[2];
54 bool vertexInputBefore;
55 bool vertexBuffersNullStride;
56 deUint32 stride;
57 bool destroyDescriptorSetLayout;
58 };
59
findDSFormat(const vk::InstanceInterface& vki, const vk::VkPhysicalDevice physicalDevice)60 vk::VkFormat findDSFormat (const vk::InstanceInterface& vki, const vk::VkPhysicalDevice physicalDevice)
61 {
62 const vk::VkFormat dsFormats[] = {
63 vk::VK_FORMAT_D24_UNORM_S8_UINT,
64 vk::VK_FORMAT_D32_SFLOAT_S8_UINT,
65 vk::VK_FORMAT_D16_UNORM_S8_UINT,
66 };
67
68 for (deUint32 i = 0; i < 3; ++i) {
69 const vk::VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, dsFormats[i]);
70 if ((formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
71 return dsFormats[i];
72 }
73 return vk::VK_FORMAT_UNDEFINED;
74 }
75
76 class ShaderObjectMiscInstance : public vkt::TestInstance
77 {
78 public:
ShaderObjectMiscInstance(Context& context, const TestParams& params)79 ShaderObjectMiscInstance (Context& context, const TestParams& params)
80 : vkt::TestInstance (context)
81 , m_params (params)
82 {}
~ShaderObjectMiscInstance(void)83 virtual ~ShaderObjectMiscInstance (void) {}
84
85 tcu::TestStatus iterate (void) override;
86 private:
87 void setVertexInput (const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkDeviceSize stride) const;
88 void bindVertexBuffers (const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkDeviceSize* stride, vk::VkBuffer buffer, vk::VkDeviceSize bufferSize) const;
89 TestParams m_params;
90 };
91
setVertexInput(const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkDeviceSize stride) const92 void ShaderObjectMiscInstance::setVertexInput (const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkDeviceSize stride) const
93 {
94 vk::VkVertexInputBindingDescription2EXT bindingDescription = vk::initVulkanStructure();
95 bindingDescription.binding = 0u;
96 bindingDescription.stride = (deUint32)stride;
97 bindingDescription.inputRate = vk::VK_VERTEX_INPUT_RATE_VERTEX;
98 bindingDescription.divisor = 1u;
99 vk::VkVertexInputAttributeDescription2EXT attributeDescription = vk::initVulkanStructure();
100 attributeDescription.location = 0u;
101 attributeDescription.binding = 0u;
102 attributeDescription.format = vk::VK_FORMAT_R32G32B32A32_SFLOAT;
103 attributeDescription.offset = 0u;
104 vk.cmdSetVertexInputEXT(cmdBuffer, 1u, &bindingDescription, 1u, &attributeDescription);
105 }
106
bindVertexBuffers(const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkDeviceSize* stride, vk::VkBuffer buffer, vk::VkDeviceSize bufferSize) const107 void ShaderObjectMiscInstance::bindVertexBuffers (const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkDeviceSize* stride, vk::VkBuffer buffer, vk::VkDeviceSize bufferSize) const
108 {
109 vk::VkDeviceSize offset = 0u;
110 vk.cmdBindVertexBuffers2(cmdBuffer, 0u, 1u, &buffer, &offset, &bufferSize, stride);
111 }
112
iterate(void)113 tcu::TestStatus ShaderObjectMiscInstance::iterate (void)
114 {
115 const vk::VkInstance instance = m_context.getInstance();
116 const vk::InstanceDriver instanceDriver (m_context.getPlatformInterface(), instance);
117 const vk::DeviceInterface& vk = m_context.getDeviceInterface();
118 const vk::VkDevice device = m_context.getDevice();
119 const vk::VkQueue queue = m_context.getUniversalQueue();
120 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
121 auto& alloc = m_context.getDefaultAllocator();
122 tcu::TestLog& log = m_context.getTestContext().getLog();
123 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
124 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
125 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
126 const bool taskSupported = m_context.getMeshShaderFeatures().taskShader;
127 const bool meshSupported = m_context.getMeshShaderFeatures().meshShader;
128
129 vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
130 const auto subresourceRange = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
131 const auto subresourceLayers = vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
132 const vk::VkRect2D renderArea = vk::makeRect2D(0, 0, 32, 32);
133 vk::VkExtent3D extent = { renderArea.extent.width, renderArea.extent.height, 1};
134
135 const vk::VkImageCreateInfo createInfo =
136 {
137 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
138 DE_NULL, // const void* pNext
139 0u, // VkImageCreateFlags flags
140 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
141 colorAttachmentFormat, // VkFormat format
142 { 32, 32, 1 }, // VkExtent3D extent
143 1u, // uint32_t mipLevels
144 1u, // uint32_t arrayLayers
145 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
146 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
147 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
148 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
149 0, // uint32_t queueFamilyIndexCount
150 DE_NULL, // const uint32_t* pQueueFamilyIndices
151 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
152 };
153
154 const deUint32 colorAttachmentCount = 2;
155
156 std::vector<de::MovePtr<vk::ImageWithMemory>> images (colorAttachmentCount);
157 std::vector<vk::Move<vk::VkImageView>> imageViews (colorAttachmentCount);
158 for (deUint32 i = 0; i < colorAttachmentCount; ++i)
159 {
160 images[i] = de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
161 imageViews[i] = vk::makeImageView(vk, device, **images[i], vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
162 }
163
164 const vk::VkDeviceSize colorOutputBufferSize = renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
165 std::vector<de::MovePtr<vk::BufferWithMemory>> colorOutputBuffers (colorAttachmentCount);
166 for (deUint32 i = 0; i < colorAttachmentCount; ++i)
167 {
168 colorOutputBuffers[i] = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
169 vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT), vk::MemoryRequirement::HostVisible));
170 }
171
172 const vk::Move<vk::VkCommandPool> cmdPool (vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
173 const vk::Move<vk::VkCommandBuffer> cmdBuffer (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
174
175 vk::Move<vk::VkDescriptorSetLayout> descriptorSetLayout(
176 vk::DescriptorSetLayoutBuilder()
177 .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_FRAGMENT_BIT)
178 .build(vk, device));
179
180 const vk::Unique<vk::VkDescriptorPool> descriptorPool(
181 vk::DescriptorPoolBuilder()
182 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
183 .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
184
185 const vk::VkDeviceSize bufferSizeBytes = sizeof(tcu::Vec4);
186 const vk::Unique<vk::VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
187 const vk::BufferWithMemory inputBuffer (vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), vk::MemoryRequirement::HostVisible);
188
189 const vk::VkDescriptorBufferInfo descriptorInfo = vk::makeDescriptorBufferInfo(*inputBuffer, 0ull, bufferSizeBytes);
190 vk::DescriptorSetUpdateBuilder()
191 .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
192 .update(vk, device);
193 const auto pipelineLayout = makePipelineLayout(vk, device, *descriptorSetLayout);
194
195 float* inputDataPtr = reinterpret_cast<float*>(inputBuffer.getAllocation().getHostPtr());
196 memset(inputDataPtr, 0, bufferSizeBytes);
197 for (deUint32 i = 0; i < 4; ++i)
198 inputDataPtr[i] = 0.5f;
199 flushAlloc(vk, device, inputBuffer.getAllocation());
200
201 const auto& binaries = m_context.getBinaryCollection();
202 const auto vertShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("inputVert"), tessellationSupported, geometrySupported, &*descriptorSetLayout));
203 const auto fragShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("multiFrag"), tessellationSupported, geometrySupported, &*descriptorSetLayout));
204
205 const vk::VkClearValue clearValue = vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 0.0f });
206 vk::beginCommandBuffer(vk, *cmdBuffer);
207
208 for (deUint32 i = 0; i < colorAttachmentCount; ++i)
209 {
210 vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **images[i], subresourceRange);
211 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &preImageBarrier);
212 }
213
214 std::vector<vk::VkRenderingAttachmentInfoKHR> colorAttachments(colorAttachmentCount);
215 vk::VkRenderingAttachmentInfoKHR colorAttachment
216 {
217 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
218 DE_NULL, // const void* pNext;
219 VK_NULL_HANDLE, // VkImageView imageView;
220 vk::VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
221 vk::VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
222 DE_NULL, // VkImageView resolveImageView;
223 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
224 vk::VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
225 vk::VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
226 clearValue // VkClearValue clearValue;
227 };
228
229 for (deUint32 i = 0; i < colorAttachmentCount; ++i)
230 {
231 colorAttachment.imageView = *imageViews[i];
232 colorAttachments[i] = colorAttachment;
233 }
234
235 vk::VkRenderingInfoKHR renderingInfo
236 {
237 vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
238 DE_NULL,
239 (vk::VkRenderingFlags)0u, // VkRenderingFlagsKHR flags;
240 renderArea, // VkRect2D renderArea;
241 1u, // deUint32 layerCount;
242 0x0, // deUint32 viewMask;
243 (deUint32)colorAttachments.size(), // deUint32 colorAttachmentCount;
244 colorAttachments.data(), // const VkRenderingAttachmentInfoKHR* pColorAttachments;
245 DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
246 DE_NULL, // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
247 };
248
249 const vk::VkDeviceSize bufferSize = 1024;
250 de::MovePtr<vk::BufferWithMemory> buffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
251 vk, device, alloc, vk::makeBufferCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), vk::MemoryRequirement::HostVisible));
252 float* dataPtr = reinterpret_cast<float*>(buffer->getAllocation().getHostPtr());
253 memset(dataPtr, 0, bufferSize);
254 for (deUint32 i = 0; i < 4; ++i)
255 {
256 dataPtr[i * (m_params.stride / sizeof(float)) + 0] = float(i & 1);
257 dataPtr[i * (m_params.stride / sizeof(float)) + 1] = float((i >> 1) & 1);
258 dataPtr[i * (m_params.stride / sizeof(float)) + 2] = 0.0f;
259 dataPtr[i * (m_params.stride / sizeof(float)) + 3] = 1.0f;
260 }
261 flushAlloc(vk, device, buffer->getAllocation());
262
263 vk::Move<vk::VkDescriptorSetLayout> null;
264 if (m_params.destroyDescriptorSetLayout)
265 descriptorSetLayout = null;
266
267 vk.cmdBeginRendering(*cmdBuffer, &renderingInfo);
268 vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, false);
269
270 vk::VkColorBlendEquationEXT colorBlendEquation = {
271 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
272 vk::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,// VkBlendFactor dstColorBlendFactor;
273 vk::VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
274 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
275 vk::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,// VkBlendFactor dstAlphaBlendFactor;
276 vk::VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
277 };
278 vk::VkColorComponentFlags colorWriteMask = vk::VK_COLOR_COMPONENT_R_BIT | vk::VK_COLOR_COMPONENT_G_BIT | vk::VK_COLOR_COMPONENT_B_BIT | vk::VK_COLOR_COMPONENT_A_BIT;
279 for (deUint32 i = 0; i < colorAttachmentCount; ++i)
280 {
281 vk::VkBool32 colorBlendEnable = m_params.blendEnabled[i] ? VK_TRUE : VK_FALSE;
282 vk.cmdSetColorBlendEnableEXT(*cmdBuffer, i, 1u, &colorBlendEnable);
283 if (m_params.blendEnabled[i])
284 {
285 vk.cmdSetColorBlendEquationEXT(*cmdBuffer, i, 1u, &colorBlendEquation);
286 }
287 vk.cmdSetColorWriteMaskEXT(*cmdBuffer, i, 1u, &colorWriteMask);
288 }
289 const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(instanceDriver, m_context.getPhysicalDevice());
290 std::vector<vk::VkBool32> colorWriteEnables(properties.limits.maxColorAttachments);
291 for (deUint32 i = 0; i < properties.limits.maxColorAttachments; ++i)
292 {
293 colorWriteEnables[i] = i < colorAttachmentCount ? VK_TRUE : VK_FALSE;
294 }
295 vk.cmdSetColorWriteEnableEXT(*cmdBuffer, properties.limits.maxColorAttachments, colorWriteEnables.data());
296
297 if (m_params.vertexInputBefore)
298 setVertexInput(vk, *cmdBuffer, m_params.vertexBuffersNullStride ? m_params.stride : 100);
299
300 vk::VkDeviceSize stride = m_params.stride;
301 vk::VkDeviceSize* pStride = m_params.vertexBuffersNullStride ? DE_NULL : &stride;
302 bindVertexBuffers(vk, *cmdBuffer, pStride, **buffer, bufferSize);
303
304 if (!m_params.vertexInputBefore)
305 setVertexInput(vk, *cmdBuffer, m_params.stride);
306
307 vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0, 1, &descriptorSet.get(), 0, DE_NULL);
308
309 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, *fragShader, taskSupported, meshSupported);
310 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
311 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
312
313 vk::endRendering(vk, *cmdBuffer);
314
315 for (deUint32 i = 0; i < colorAttachmentCount; ++i)
316 {
317 vk::VkImageMemoryBarrier postImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **images[i], subresourceRange);
318 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarrier);
319 }
320
321 const vk::VkBufferImageCopy copyRegion = vk::makeBufferImageCopy(extent, subresourceLayers);
322 for (deUint32 i = 0; i < colorAttachmentCount; ++i)
323 vk.cmdCopyImageToBuffer(*cmdBuffer, **images[i], vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffers[i], 1u, ©Region);
324
325 vk::endCommandBuffer(vk, *cmdBuffer);
326
327 vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
328
329 const deInt32 width = renderArea.extent.width;
330 const deInt32 height = renderArea.extent.height;
331 const float threshold = 1.0f / 256.0f;
332 const deInt32 xOffset = width / 8;
333 const deInt32 yOffset = height / 8;
334 const tcu::Vec4 refColor1 = tcu::Vec4(0.75f, 0.75f, 0.75f, 0.75f);
335 const tcu::Vec4 refColor2 = tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f);
336 const tcu::Vec4 blackColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
337
338 for (deUint32 k = 0; k < colorAttachmentCount; ++k)
339 {
340 tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(vk::mapVkFormat(colorAttachmentFormat), renderArea.extent.width, renderArea.extent.height, 1, (const void*)colorOutputBuffers[k]->getAllocation().getHostPtr());
341 for (deInt32 j = 0; j < height; ++j)
342 {
343 for (deInt32 i = 0; i < width; ++i)
344 {
345 const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
346
347 tcu::Vec4 expectedColor = blackColor;
348 if (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset)
349 {
350 if (m_params.blendEnabled[k])
351 expectedColor = refColor1;
352 else
353 expectedColor = refColor2;
354 }
355
356 if (deFloatAbs(color.x() - expectedColor.x()) > threshold || deFloatAbs(color.y() - expectedColor.y()) > threshold || deFloatAbs(color.z() - expectedColor.z()) > threshold || deFloatAbs(color.w() - expectedColor.w()) > threshold)
357 {
358 log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") was " << color << ", but expected color was " << expectedColor << tcu::TestLog::EndMessage;
359 return tcu::TestStatus::fail("Fail");
360 }
361 }
362 }
363 }
364
365 return tcu::TestStatus::pass("Pass");
366 }
367
368 class ShaderObjectMiscCase : public vkt::TestCase
369 {
370 public:
371 ShaderObjectMiscCase (tcu::TestContext& testCtx, const std::string& name, const TestParams& params)
372 : vkt::TestCase (testCtx, name)
373 , m_params (params)
374 {}
375 virtual ~ShaderObjectMiscCase (void) {}
376
377 void checkSupport (vkt::Context& context) const override;
378 virtual void initPrograms (vk::SourceCollections& programCollection) const override;
379 TestInstance* createInstance (Context& context) const override { return new ShaderObjectMiscInstance(context, m_params); }
380 private:
381 TestParams m_params;
382 };
383
384 void ShaderObjectMiscCase::checkSupport (Context& context) const
385 {
386 context.requireDeviceFunctionality("VK_EXT_shader_object");
387 }
388
389 void ShaderObjectMiscCase::initPrograms (vk::SourceCollections& programCollection) const
390 {
391 std::stringstream inputVert;
392 std::stringstream multiFrag;
393
394 inputVert
395 << "#version 450\n"
396 << "layout(location = 0) in vec4 inPos;\n"
397 << "void main() {\n"
398 << " gl_Position = vec4((inPos.xy - 0.5f) * 1.5f, inPos.zw);\n"
399 << "}\n";
400
401 multiFrag
402 << "#version 450\n"
403 << "layout(set=0, binding=0) readonly buffer inputBuf {\n"
404 << " vec4 color;\n"
405 << "};\n"
406 << "layout (location=0) out vec4 outColor0;\n"
407 << "layout (location=1) out vec4 outColor1;\n"
408 << "void main() {\n"
409 << " outColor0 = color;\n"
410 << " outColor1 = color;\n"
411 << "}\n";
412
413 programCollection.glslSources.add("inputVert") << glu::VertexSource(inputVert.str());
414 programCollection.glslSources.add("multiFrag") << glu::FragmentSource(multiFrag.str());
415 }
416
417 de::MovePtr<tcu::TextureLevel> readDepthAttachment (const vk::DeviceInterface& vk,
418 vk::VkDevice device,
419 vk::VkQueue queue,
420 deUint32 queueFamilyIndex,
421 vk::Allocator& allocator,
422 vk::VkImage image,
423 vk::VkFormat format,
424 const tcu::UVec2& renderSize,
425 vk::VkImageLayout currentLayout)
426 {
427 vk::Move<vk::VkBuffer> buffer;
428 de::MovePtr<vk::Allocation> bufferAlloc;
429 vk::Move<vk::VkCommandPool> cmdPool;
430 vk::Move<vk::VkCommandBuffer> cmdBuffer;
431
432 tcu::TextureFormat retFormat (tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST);
433 tcu::TextureFormat bufferFormat (tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST);
434 const vk::VkImageAspectFlags barrierAspect = vk::VK_IMAGE_ASPECT_DEPTH_BIT | (mapVkFormat(format).order == tcu::TextureFormat::DS ? vk::VK_IMAGE_ASPECT_STENCIL_BIT : (vk::VkImageAspectFlagBits)0);
435
436 switch (format)
437 {
438 case vk::VK_FORMAT_D16_UNORM:
439 case vk::VK_FORMAT_D16_UNORM_S8_UINT:
440 bufferFormat.type = retFormat.type = tcu::TextureFormat::UNORM_INT16;
441 break;
442 case vk::VK_FORMAT_D24_UNORM_S8_UINT:
443 case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
444 retFormat.type = tcu::TextureFormat::UNORM_INT24;
445 // vkCmdCopyBufferToImage copies D24 data to 32-bit pixels.
446 bufferFormat.type = tcu::TextureFormat::UNSIGNED_INT_24_8_REV;
447 break;
448 case vk::VK_FORMAT_D32_SFLOAT:
449 case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
450 bufferFormat.type = retFormat.type = tcu::TextureFormat::FLOAT;
451 break;
452 default:
453 TCU_FAIL("unrecognized format");
454 }
455
456 const vk::VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * bufferFormat.getPixelSize();
457 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(retFormat, renderSize.x(), renderSize.y()));
458
459 // Create destination buffer
460 {
461 const vk::VkBufferCreateInfo bufferParams =
462 {
463 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
464 DE_NULL, // const void* pNext;
465 0u, // VkBufferCreateFlags flags;
466 pixelDataSize, // VkDeviceSize size;
467 vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
468 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
469 0u, // deUint32 queueFamilyIndexCount;
470 DE_NULL // const deUint32* pQueueFamilyIndices;
471 };
472
473 buffer = createBuffer(vk, device, &bufferParams);
474 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), vk::MemoryRequirement::HostVisible);
475 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
476 }
477
478 // Create command pool and buffer
479 cmdPool = createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
480 cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
481
482 beginCommandBuffer(vk, *cmdBuffer);
483 copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()), vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, currentLayout, 1u, barrierAspect, vk::VK_IMAGE_ASPECT_DEPTH_BIT);
484 endCommandBuffer(vk, *cmdBuffer);
485
486 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
487
488 // Read buffer data
489 invalidateAlloc(vk, device, *bufferAlloc);
490 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(bufferFormat, resultLevel->getSize(), bufferAlloc->getHostPtr()));
491
492 return resultLevel;
493 }
494
495 de::MovePtr<tcu::TextureLevel> readStencilAttachment (const vk::DeviceInterface& vk,
496 vk::VkDevice device,
497 vk::VkQueue queue,
498 deUint32 queueFamilyIndex,
499 vk::Allocator& allocator,
500 vk::VkImage image,
501 vk::VkFormat format,
502 const tcu::UVec2& renderSize,
503 vk::VkImageLayout currentLayout)
504 {
505 vk::Move<vk::VkBuffer> buffer;
506 de::MovePtr<vk::Allocation> bufferAlloc;
507 vk::Move<vk::VkCommandPool> cmdPool;
508 vk::Move<vk::VkCommandBuffer> cmdBuffer;
509
510 tcu::TextureFormat retFormat (tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
511 tcu::TextureFormat bufferFormat (tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
512
513 const vk::VkImageAspectFlags barrierAspect = vk::VK_IMAGE_ASPECT_STENCIL_BIT | (mapVkFormat(format).order == tcu::TextureFormat::DS ? vk::VK_IMAGE_ASPECT_DEPTH_BIT : (vk::VkImageAspectFlagBits)0);
514 const vk::VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * bufferFormat.getPixelSize();
515 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(retFormat, renderSize.x(), renderSize.y()));
516
517 // Create destination buffer
518 {
519 const vk::VkBufferCreateInfo bufferParams =
520 {
521 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
522 DE_NULL, // const void* pNext;
523 0u, // VkBufferCreateFlags flags;
524 pixelDataSize, // VkDeviceSize size;
525 vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
526 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
527 0u, // deUint32 queueFamilyIndexCount;
528 DE_NULL // const deUint32* pQueueFamilyIndices;
529 };
530
531 buffer = createBuffer(vk, device, &bufferParams);
532 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), vk::MemoryRequirement::HostVisible);
533 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
534 }
535
536 // Create command pool and buffer
537 cmdPool = createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
538 cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
539
540 beginCommandBuffer(vk, *cmdBuffer);
541 copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()), vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, currentLayout, 1u, barrierAspect, vk::VK_IMAGE_ASPECT_STENCIL_BIT);
542 endCommandBuffer(vk, *cmdBuffer);
543
544 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
545
546 // Read buffer data
547 invalidateAlloc(vk, device, *bufferAlloc);
548 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(bufferFormat, resultLevel->getSize(), bufferAlloc->getHostPtr()));
549
550 return resultLevel;
551 }
552
553 struct StateTestParams {
554 bool pipeline;
555 bool meshShader;
556 bool vertShader;
557 bool tessShader;
558 bool geomShader;
559 bool fragShader;
560 bool logicOp;
561 bool alphaToOne;
562 bool depthBounds;
563 bool depthClamp;
564 bool depthClip;
565 bool depthClipControl;
566 bool colorWrite;
567 bool geometryStreams;
568 bool discardRectangles;
569 bool conservativeRasterization;
570 bool rasterizerDiscardEnable;
571 bool lines;
572 bool sampleLocations;
573 bool provokingVertex;
574 bool lineRasterization;
575 bool cull;
576 bool stencilTestEnable;
577 bool depthTestEnable;
578 bool depthBiasEnable;
579 bool depthBoundsTestEnable;
580 bool logicOpEnable;
581 bool colorBlendEnable;
582 bool discardRectanglesEnable;
583 bool sampleLocationsEnable;
584 bool conservativeRasterizationOverestimate;
585 bool stippledLineEnable;
586 bool colorWriteEnable;
587
588 void reset()
589 {
590 logicOp = false;
591 alphaToOne = false;
592 depthBounds = false;
593 depthClamp = false;
594 depthClip = false;
595 depthClipControl = false;
596 colorWrite = true;
597 geometryStreams = false;
598 discardRectangles = false;
599 conservativeRasterization = false;
600 rasterizerDiscardEnable = false;
601 lines = false;
602 sampleLocations = false;
603 provokingVertex = false;
604 lineRasterization = false;
605 cull = false;
606 stencilTestEnable = false;
607 depthTestEnable = false;
608 depthBiasEnable = false;
609 depthBoundsTestEnable = false;
610 logicOpEnable = false;
611 colorBlendEnable = false;
612 discardRectanglesEnable = false;
613 sampleLocationsEnable = false;
614 conservativeRasterizationOverestimate = false;
615 stippledLineEnable = false;
616 colorWriteEnable = true;
617 }
618 };
619
620 class ShaderObjectStateInstance : public vkt::TestInstance
621 {
622 public:
623 ShaderObjectStateInstance (Context& context, const StateTestParams& testParams)
624 : vkt::TestInstance (context)
625 , m_params (testParams)
626 {}
627 virtual ~ShaderObjectStateInstance (void) {}
628
629 tcu::TestStatus iterate (void) override;
630
631 private:
632 void createDevice (void);
633 std::vector<vk::VkDynamicState> getDynamicStates (void) const;
634 bool hasDynamicState (const std::vector<vk::VkDynamicState> dynamicStates, const vk::VkDynamicState dynamicState);
635 void setDynamicStates (const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer);
636 bool isInsidePrimitive (deUint32 i, deUint32 j, deUint32 width, deUint32 height);
637
638 vk::Move<vk::VkDevice> m_customDevice;
639 de::MovePtr<vk::DeviceDriver> m_logicalDeviceInterface;
640 vk::VkQueue m_logicalDeviceQueue;
641 const StateTestParams m_params;
642 };
643
644 void ShaderObjectStateInstance::createDevice (void)
645 {
646 vk::VkPhysicalDeviceMeshShaderFeaturesEXT meshShaderFeatuers = vk::initVulkanStructure();
647 vk::VkPhysicalDeviceColorWriteEnableFeaturesEXT colorWriteEnableFeatures = vk::initVulkanStructure();
648 vk::VkPhysicalDeviceDepthClipControlFeaturesEXT depthClipControlFeatures = vk::initVulkanStructure();
649 vk::VkPhysicalDeviceDepthClipEnableFeaturesEXT depthClipEnableFeatures = vk::initVulkanStructure();
650 vk::VkPhysicalDeviceTransformFeedbackFeaturesEXT transformFeedbackFeatures = vk::initVulkanStructure();
651 vk::VkPhysicalDeviceLineRasterizationFeaturesEXT lineRasterizationFeatures = vk::initVulkanStructure();
652
653 vk::VkPhysicalDeviceDynamicRenderingFeatures dynamicRenderingFeatures = m_context.getDynamicRenderingFeatures();
654 vk::VkPhysicalDeviceShaderObjectFeaturesEXT shaderObjectFeatures = m_context.getShaderObjectFeaturesEXT();
655
656 vk::VkPhysicalDeviceExtendedDynamicStateFeaturesEXT edsFeatures = m_context.getExtendedDynamicStateFeaturesEXT();
657 vk::VkPhysicalDeviceExtendedDynamicState2FeaturesEXT eds2Features = m_context.getExtendedDynamicState2FeaturesEXT();
658 vk::VkPhysicalDeviceExtendedDynamicState3FeaturesEXT eds3Features = m_context.getExtendedDynamicState3FeaturesEXT();
659 vk::VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT viFeatures = m_context.getVertexInputDynamicStateFeaturesEXT();
660
661 dynamicRenderingFeatures.pNext = DE_NULL;
662 shaderObjectFeatures.pNext = DE_NULL;
663 edsFeatures.pNext = DE_NULL;
664 eds2Features.pNext = DE_NULL;
665 eds3Features.pNext = DE_NULL;
666 viFeatures.pNext = DE_NULL;
667
668 vk::VkPhysicalDeviceFeatures2 features2 = vk::initVulkanStructure();
669 void* pNext = &dynamicRenderingFeatures;
670
671 const float queuePriority = 1.0f;
672 std::vector<const char*> deviceExtensions = { "VK_KHR_dynamic_rendering" };
673 if (m_params.pipeline)
674 {
675 const auto& deviceExts = m_context.getDeviceExtensions();
676 if (std::find(deviceExts.begin(), deviceExts.end(), "VK_EXT_extended_dynamic_state") != deviceExts.end())
677 {
678 deviceExtensions.push_back("VK_EXT_extended_dynamic_state");
679 edsFeatures.pNext = pNext;
680 pNext = &edsFeatures;
681 }
682 if (std::find(deviceExts.begin(), deviceExts.end(), "VK_EXT_extended_dynamic_state2") != deviceExts.end())
683 {
684 deviceExtensions.push_back("VK_EXT_extended_dynamic_state2");
685 eds2Features.pNext = pNext;
686 pNext = &eds2Features;
687 }
688 if (std::find(deviceExts.begin(), deviceExts.end(), "VK_EXT_extended_dynamic_state3") != deviceExts.end())
689 {
690 deviceExtensions.push_back("VK_EXT_extended_dynamic_state3");
691 eds3Features.pNext = pNext;
692 pNext = &eds3Features;
693 }
694 if (std::find(deviceExts.begin(), deviceExts.end(), "VK_EXT_vertex_input_dynamic_state") != deviceExts.end())
695 {
696 deviceExtensions.push_back("VK_EXT_vertex_input_dynamic_state");
697 viFeatures.pNext = pNext;
698 pNext = &viFeatures;
699 }
700 }
701 else
702 {
703 deviceExtensions.push_back("VK_EXT_shader_object");
704 dynamicRenderingFeatures.pNext = &shaderObjectFeatures;
705 }
706
707 if (m_params.tessShader)
708 features2.features.tessellationShader = VK_TRUE;
709 if (m_params.geomShader)
710 features2.features.geometryShader = VK_TRUE;
711
712 if (m_params.logicOp)
713 features2.features.logicOp = VK_TRUE;
714 if (m_params.alphaToOne)
715 features2.features.alphaToOne = VK_TRUE;
716 if (m_params.depthBounds)
717 features2.features.depthBounds = VK_TRUE;
718 if (m_params.depthClamp)
719 features2.features.depthClamp = VK_TRUE;
720 if (m_params.depthBiasEnable)
721 features2.features.depthBiasClamp = VK_TRUE;
722 if (m_params.depthClip)
723 {
724 depthClipEnableFeatures.pNext = pNext;
725 pNext = &depthClipEnableFeatures;
726 depthClipEnableFeatures.depthClipEnable = VK_TRUE;
727 deviceExtensions.push_back("VK_EXT_depth_clip_enable");
728 }
729 if (m_params.depthClipControl)
730 {
731 depthClipControlFeatures.pNext = pNext;
732 pNext = &depthClipControlFeatures;
733 depthClipControlFeatures.depthClipControl = VK_TRUE;
734 deviceExtensions.push_back("VK_EXT_depth_clip_control");
735 }
736 if (m_params.colorWrite)
737 {
738 colorWriteEnableFeatures.pNext = pNext;
739 pNext = &colorWriteEnableFeatures;
740 colorWriteEnableFeatures.colorWriteEnable = VK_TRUE;
741 deviceExtensions.push_back("VK_EXT_color_write_enable");
742 }
743 if (m_params.geometryStreams)
744 {
745 transformFeedbackFeatures.pNext = pNext;
746 pNext = &transformFeedbackFeatures;
747 transformFeedbackFeatures.transformFeedback = VK_TRUE;
748 transformFeedbackFeatures.geometryStreams = VK_TRUE;
749 deviceExtensions.push_back("VK_EXT_transform_feedback");
750 }
751 if (m_params.sampleLocations)
752 deviceExtensions.push_back("VK_EXT_sample_locations");
753 if (m_params.discardRectangles)
754 deviceExtensions.push_back("VK_EXT_discard_rectangles");
755 if (m_params.conservativeRasterization)
756 deviceExtensions.push_back("VK_EXT_conservative_rasterization");
757 if (m_params.sampleLocations)
758 deviceExtensions.push_back("VK_EXT_sample_locations");
759 if (m_params.provokingVertex)
760 deviceExtensions.push_back("VK_EXT_provoking_vertex");
761 if (m_params.lineRasterization)
762 {
763 lineRasterizationFeatures.pNext = pNext;
764 pNext = &lineRasterizationFeatures;
765 lineRasterizationFeatures.rectangularLines = VK_TRUE;
766 deviceExtensions.push_back("VK_EXT_line_rasterization");
767 }
768 if (m_params.meshShader)
769 {
770 meshShaderFeatuers.pNext = pNext;
771 pNext = &meshShaderFeatuers;
772 meshShaderFeatuers.meshShader = VK_TRUE;
773 deviceExtensions.push_back("VK_EXT_mesh_shader");
774 }
775
776 features2.pNext = pNext;
777
778 vk::VkDeviceQueueCreateInfo queueInfo =
779 {
780 vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
781 DE_NULL, // const void* pNext;
782 0u, // VkDeviceQueueCreateFlags flags;
783 0u, // deUint32 queueFamilyIndex;
784 1u, // deUint32 queueCount;
785 &queuePriority // const float* pQueuePriorities;
786 };
787
788 const vk::VkDeviceCreateInfo deviceInfo =
789 {
790 vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType;
791 &features2, // const void* pNext;
792 (vk::VkDeviceCreateFlags)0, // VkDeviceCreateFlags flags;
793 1u, // uint32_t queueCreateInfoCount;
794 &queueInfo, // const VkDeviceQueueCreateInfo* pQueueCreateInfos;
795 0u, // uint32_t enabledLayerCount;
796 DE_NULL, // const char* const* ppEnabledLayerNames;
797 deUint32(deviceExtensions.size()), // uint32_t enabledExtensionCount;
798 deviceExtensions.data(), // const char* const* ppEnabledExtensionNames;
799 DE_NULL // const VkPhysicalDeviceFeatures* pEnabledFeatures;
800 };
801
802 m_customDevice = createCustomDevice(m_context.getTestContext().getCommandLine().isValidationEnabled(), m_context.getPlatformInterface(), m_context.getInstance(), m_context.getInstanceInterface(), m_context.getPhysicalDevice(), &deviceInfo);
803 m_logicalDeviceInterface = de::MovePtr<vk::DeviceDriver>(new vk::DeviceDriver(m_context.getPlatformInterface(), m_context.getInstance(), *m_customDevice, m_context.getUsedApiVersion()));
804 m_logicalDeviceInterface->getDeviceQueue(*m_customDevice, m_context.getUniversalQueueFamilyIndex(), 0, &m_logicalDeviceQueue);
805 }
806
807 std::vector<vk::VkDynamicState> ShaderObjectStateInstance::getDynamicStates (void) const
808 {
809 const auto& edsFeatures = m_context.getExtendedDynamicStateFeaturesEXT();
810 const auto& eds2Features = m_context.getExtendedDynamicState2FeaturesEXT();
811 const auto& eds3Features = m_context.getExtendedDynamicState3FeaturesEXT();
812 const auto& viFeatures = m_context.getVertexInputDynamicStateFeaturesEXT();
813
814 std::vector<vk::VkDynamicState> dynamicStates;
815
816 if (edsFeatures.extendedDynamicState)
817 {
818 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT);
819 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT);
820 }
821
822 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_WIDTH);
823 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BIAS);
824 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_BLEND_CONSTANTS);
825 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS);
826 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK);
827 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_WRITE_MASK);
828 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_REFERENCE);
829 if (edsFeatures.extendedDynamicState && !m_params.meshShader && !m_params.pipeline)
830 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE);
831 if (edsFeatures.extendedDynamicState)
832 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CULL_MODE);
833 if (edsFeatures.extendedDynamicState)
834 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE);
835 if (edsFeatures.extendedDynamicState)
836 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_COMPARE_OP);
837 if (edsFeatures.extendedDynamicState)
838 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE);
839 if (edsFeatures.extendedDynamicState)
840 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE);
841 if (edsFeatures.extendedDynamicState)
842 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_FRONT_FACE);
843 if (edsFeatures.extendedDynamicState && !m_params.meshShader)
844 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY);
845 if (edsFeatures.extendedDynamicState)
846 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_OP);
847 if (edsFeatures.extendedDynamicState)
848 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE);
849 if (eds2Features.extendedDynamicState2)
850 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE);
851 if (eds2Features.extendedDynamicState2 && !m_params.meshShader)
852 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE);
853 if (eds2Features.extendedDynamicState2)
854 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT);
855 if (viFeatures.vertexInputDynamicState && !m_params.meshShader && !m_params.pipeline)
856 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT);
857 if (eds2Features.extendedDynamicState2LogicOp)
858 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LOGIC_OP_EXT);
859 if (eds2Features.extendedDynamicState2PatchControlPoints && !m_params.meshShader)
860 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT);
861 if (eds3Features.extendedDynamicState3TessellationDomainOrigin)
862 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT);
863 if (eds3Features.extendedDynamicState3DepthClampEnable)
864 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT);
865 if (eds3Features.extendedDynamicState3PolygonMode)
866 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT);
867 if (eds3Features.extendedDynamicState3RasterizationSamples)
868 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT);
869 if (eds3Features.extendedDynamicState3SampleMask)
870 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_MASK_EXT);
871 if (eds3Features.extendedDynamicState3AlphaToCoverageEnable)
872 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT);
873 if (eds3Features.extendedDynamicState3AlphaToOneEnable)
874 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT);
875 if (eds3Features.extendedDynamicState3LogicOpEnable)
876 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT);
877 if (eds3Features.extendedDynamicState3ColorBlendEnable)
878 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT);
879 if (eds3Features.extendedDynamicState3ColorBlendEquation)
880 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT);
881 if (eds3Features.extendedDynamicState3ColorWriteMask)
882 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT);
883 if (eds3Features.extendedDynamicState3RasterizationStream && m_params.geometryStreams)
884 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT);
885 if (m_params.discardRectangles)
886 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT);
887 if (m_params.discardRectangles)
888 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT);
889 if (m_params.discardRectangles)
890 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT);
891 if (eds3Features.extendedDynamicState3ConservativeRasterizationMode && m_params.conservativeRasterization)
892 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT);
893 if (eds3Features.extendedDynamicState3ExtraPrimitiveOverestimationSize && m_params.conservativeRasterization)
894 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT);
895 if (eds3Features.extendedDynamicState3DepthClipEnable && m_params.depthClip)
896 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT);
897 if (eds3Features.extendedDynamicState3SampleLocationsEnable && m_params.sampleLocations)
898 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT);
899 if (m_params.sampleLocations)
900 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT);
901 if (eds3Features.extendedDynamicState3ProvokingVertexMode && m_params.provokingVertex)
902 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT);
903 if (eds3Features.extendedDynamicState3LineRasterizationMode && m_params.lineRasterization)
904 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT);
905 if (eds3Features.extendedDynamicState3LineStippleEnable && m_params.lineRasterization)
906 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT);
907 if (m_params.lineRasterization)
908 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_EXT);
909 if (eds3Features.extendedDynamicState3DepthClipNegativeOneToOne && m_params.depthClipControl)
910 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT);
911 if (m_params.colorWrite)
912 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT);
913 return dynamicStates;
914 }
915
916 bool ShaderObjectStateInstance::hasDynamicState(const std::vector<vk::VkDynamicState> dynamicStates, const vk::VkDynamicState dynamicState)
917 {
918 if (!m_params.pipeline)
919 return false;
920 return std::find(dynamicStates.begin(), dynamicStates.end(), dynamicState) != dynamicStates.end();
921 }
922
923 bool extensionEnabled (const std::vector<std::string>& deviceExtensions, const std::string& ext)
924 {
925 return std::find(deviceExtensions.begin(), deviceExtensions.end(), ext) != deviceExtensions.end();
926 }
927
928 void ShaderObjectStateInstance::setDynamicStates (const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer)
929 {
930 const auto dynamicStates = getDynamicStates();
931 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
932
933 vk::VkViewport viewport = { 0, 0, 32, 32, 0.0f, 1.0f, };
934 if (m_params.depthClamp)
935 viewport.maxDepth = 0.5f;
936 if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT))
937 vk.cmdSetViewportWithCount(cmdBuffer, 1u, &viewport);
938 vk::VkRect2D scissor = { { 0, 0, }, { 32, 32, }, };
939 if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT))
940 vk.cmdSetScissorWithCount(cmdBuffer, 1u, &scissor);
941 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.lines) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LINE_WIDTH))
942 vk.cmdSetLineWidth(cmdBuffer, 1.0f);
943 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.depthBiasEnable))
944 vk.cmdSetDepthBias(cmdBuffer, 4.0f, 1.0f, 4.0f);
945 else if (hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_BIAS))
946 vk.cmdSetDepthBias(cmdBuffer, 1.0f, 0.0f, 1.0f);
947 float blendConstants[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
948 if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable && m_params.colorBlendEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_BLEND_CONSTANTS))
949 vk.cmdSetBlendConstants(cmdBuffer, blendConstants);
950 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.depthBoundsTestEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS))
951 vk.cmdSetDepthBounds(cmdBuffer, 0.2f, 0.3f);
952 vk.cmdSetStencilCompareMask(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFFFFFFF);
953 vk.cmdSetStencilWriteMask(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFFFFFFF);
954 vk.cmdSetStencilReference(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFFFFFFF);
955 if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE))
956 vk.cmdBindVertexBuffers2(cmdBuffer, 0, 0, DE_NULL, DE_NULL, DE_NULL, DE_NULL);
957 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_CULL_MODE))
958 vk.cmdSetCullMode(cmdBuffer, m_params.cull ? vk::VK_CULL_MODE_FRONT_AND_BACK : vk::VK_CULL_MODE_NONE);
959 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.depthBounds) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS))
960 vk.cmdSetDepthBoundsTestEnable(cmdBuffer, m_params.depthBoundsTestEnable ? VK_TRUE : VK_FALSE);
961 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_COMPARE_OP))
962 vk.cmdSetDepthCompareOp(cmdBuffer, vk::VK_COMPARE_OP_LESS);
963 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE))
964 vk.cmdSetDepthTestEnable(cmdBuffer, VK_TRUE);
965 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE))
966 vk.cmdSetDepthWriteEnable(cmdBuffer, VK_TRUE);
967 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && (m_params.cull || m_params.stencilTestEnable)) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_FRONT_FACE))
968 vk.cmdSetFrontFace(cmdBuffer, vk::VK_FRONT_FACE_CLOCKWISE);
969 if ((!m_params.pipeline && m_params.vertShader) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY))
970 {
971 if (m_params.tessShader)
972 vk.cmdSetPrimitiveTopology(cmdBuffer, vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
973 else if (m_params.lines)
974 vk.cmdSetPrimitiveTopology(cmdBuffer, vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST);
975 else
976 vk.cmdSetPrimitiveTopology(cmdBuffer, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
977 }
978 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.stencilTestEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_STENCIL_OP))
979 vk.cmdSetStencilOp(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, vk::VK_STENCIL_OP_REPLACE, vk::VK_STENCIL_OP_REPLACE, vk::VK_STENCIL_OP_REPLACE, vk::VK_COMPARE_OP_GREATER);
980 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE))
981 vk.cmdSetStencilTestEnable(cmdBuffer, m_params.stencilTestEnable ? VK_TRUE : VK_FALSE);
982 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE))
983 vk.cmdSetDepthBiasEnable(cmdBuffer, m_params.depthBiasEnable ? VK_TRUE : VK_FALSE);
984 if ((!m_params.pipeline && m_params.vertShader) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE))
985 vk.cmdSetPrimitiveRestartEnable(cmdBuffer, VK_FALSE);
986 if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE))
987 vk.cmdSetRasterizerDiscardEnable(cmdBuffer, m_params.rasterizerDiscardEnable ? VK_TRUE : VK_FALSE);
988 if ((!m_params.pipeline && m_params.vertShader) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE))
989 if (extensionEnabled(deviceExtensions, "VK_EXT_shader_object") || extensionEnabled(deviceExtensions, "VK_EXT_vertex_input_dynamic_state"))
990 vk.cmdSetVertexInputEXT(cmdBuffer, 0u, DE_NULL, 0u, DE_NULL);
991 if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable && m_params.logicOpEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LOGIC_OP_EXT))
992 vk.cmdSetLogicOpEXT(cmdBuffer, vk::VK_LOGIC_OP_COPY);
993 if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT))
994 vk.cmdSetPatchControlPointsEXT(cmdBuffer, 4u);
995 if ((!m_params.pipeline && m_params.tessShader) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT))
996 vk.cmdSetTessellationDomainOriginEXT(cmdBuffer, vk::VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT);
997 if (!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.depthClamp)
998 vk.cmdSetDepthClampEnableEXT(cmdBuffer, VK_TRUE);
999 else if (hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT))
1000 vk.cmdSetDepthClampEnableEXT(cmdBuffer, m_params.depthClamp ? VK_TRUE : VK_FALSE);
1001 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT))
1002 vk.cmdSetPolygonModeEXT(cmdBuffer, vk::VK_POLYGON_MODE_FILL);
1003 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT))
1004 vk.cmdSetRasterizationSamplesEXT(cmdBuffer, vk::VK_SAMPLE_COUNT_1_BIT);
1005 vk::VkSampleMask sampleMask = 0xFFFFFFFF;
1006 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_SAMPLE_MASK_EXT))
1007 vk.cmdSetSampleMaskEXT(cmdBuffer, vk::VK_SAMPLE_COUNT_1_BIT, &sampleMask);
1008 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT))
1009 vk.cmdSetAlphaToCoverageEnableEXT(cmdBuffer, VK_FALSE);
1010 if (!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.alphaToOne)
1011 vk.cmdSetAlphaToOneEnableEXT(cmdBuffer, VK_TRUE);
1012 else if (hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT))
1013 vk.cmdSetAlphaToOneEnableEXT(cmdBuffer, m_params.alphaToOne ? VK_TRUE : VK_FALSE);
1014 if (!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable && m_params.logicOp)
1015 vk.cmdSetLogicOpEnableEXT(cmdBuffer, m_params.logicOpEnable ? VK_TRUE : VK_FALSE);
1016 else if (hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT))
1017 vk.cmdSetLogicOpEnableEXT(cmdBuffer, m_params.logicOpEnable ? VK_TRUE : VK_FALSE);
1018 vk::VkBool32 colorBlendEnable = m_params.colorBlendEnable ? VK_TRUE : VK_FALSE;
1019 if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT))
1020 vk.cmdSetColorBlendEnableEXT(cmdBuffer, 0u, 1u, &colorBlendEnable);
1021 vk::VkColorBlendEquationEXT colorBlendEquation = {
1022 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
1023 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor;
1024 vk::VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
1025 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
1026 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor;
1027 vk::VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
1028 };
1029 if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT))
1030 vk.cmdSetColorBlendEquationEXT(cmdBuffer, 0u, 1u, &colorBlendEquation);
1031 vk::VkColorComponentFlags colorWriteMask = vk::VK_COLOR_COMPONENT_R_BIT | vk::VK_COLOR_COMPONENT_G_BIT | vk::VK_COLOR_COMPONENT_B_BIT | vk::VK_COLOR_COMPONENT_A_BIT;
1032 if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT))
1033 vk.cmdSetColorWriteMaskEXT(cmdBuffer, 0u, 1u, &colorWriteMask);
1034 if ((!m_params.pipeline && m_params.geomShader && m_params.geometryStreams) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT))
1035 vk.cmdSetRasterizationStreamEXT(cmdBuffer, 0u);
1036 if (m_params.discardRectangles)
1037 vk.cmdSetDiscardRectangleEnableEXT(cmdBuffer, m_params.discardRectanglesEnable ? VK_TRUE : VK_FALSE);
1038 if ((!m_params.pipeline && m_params.discardRectanglesEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT))
1039 vk.cmdSetDiscardRectangleModeEXT(cmdBuffer, vk::VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT);
1040 if ((!m_params.pipeline && m_params.discardRectanglesEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT))
1041 vk.cmdSetDiscardRectangleEXT(cmdBuffer, 0u, 1u, &scissor);
1042 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.conservativeRasterization) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT))
1043 vk.cmdSetConservativeRasterizationModeEXT(cmdBuffer, m_params.conservativeRasterizationOverestimate ? vk::VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT : vk::VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT);
1044 if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.conservativeRasterization && m_params.conservativeRasterizationOverestimate) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT))
1045 vk.cmdSetExtraPrimitiveOverestimationSizeEXT(cmdBuffer, de::min(1.0f, m_context.getConservativeRasterizationPropertiesEXT().maxExtraPrimitiveOverestimationSize));
1046 if ((!m_params.pipeline && m_params.depthClip) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT))
1047 vk.cmdSetDepthClipEnableEXT(cmdBuffer, VK_TRUE);
1048 if ((!m_params.pipeline && m_params.sampleLocations) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT))
1049 vk.cmdSetSampleLocationsEnableEXT(cmdBuffer, m_params.sampleLocationsEnable ? VK_TRUE : VK_FALSE);
1050 vk::VkSampleLocationEXT sampleLocation = { 0.5f, 0.5f };
1051 const vk::VkSampleLocationsInfoEXT sampleLocationsInfo =
1052 {
1053 vk::VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT, // VkStructureType sType;
1054 DE_NULL, // const void* pNext;
1055 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits sampleLocationsPerPixel;
1056 { 1u, 1u }, // VkExtent2D sampleLocationGridSize;
1057 1, // uint32_t sampleLocationsCount;
1058 &sampleLocation, // const VkSampleLocationEXT* pSampleLocations;
1059 };
1060 if ((!m_params.pipeline && m_params.sampleLocations && m_params.sampleLocationsEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT))
1061 vk.cmdSetSampleLocationsEXT(cmdBuffer, &sampleLocationsInfo);
1062 if ((!m_params.pipeline && m_params.provokingVertex) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT))
1063 vk.cmdSetProvokingVertexModeEXT(cmdBuffer, vk::VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT);
1064 if (m_params.pipeline || (!m_params.rasterizerDiscardEnable && m_params.lineRasterization && m_params.lines))
1065 {
1066 if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT))
1067 vk.cmdSetLineRasterizationModeEXT(cmdBuffer, vk::VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT);
1068 if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT))
1069 vk.cmdSetLineStippleEnableEXT(cmdBuffer, m_params.stippledLineEnable ? VK_TRUE : VK_FALSE);
1070 if ((!m_params.pipeline && m_params.stippledLineEnable) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LINE_STIPPLE_EXT))
1071 vk.cmdSetLineStippleEXT(cmdBuffer, 1u, 0x1);
1072 }
1073 if ((!m_params.pipeline && m_params.depthClipControl) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT))
1074 vk.cmdSetDepthClipNegativeOneToOneEXT(cmdBuffer, VK_TRUE);
1075 vk::VkBool32 colorWriteEnable = m_params.colorWriteEnable ? VK_TRUE : VK_FALSE;
1076 if ((!m_params.pipeline && m_params.colorWrite) || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT))
1077 vk.cmdSetColorWriteEnableEXT(cmdBuffer, 1u, &colorWriteEnable);
1078 }
1079
1080 bool ShaderObjectStateInstance::isInsidePrimitive (deUint32 i, deUint32 j, deUint32 width, deUint32 height)
1081 {
1082 deUint32 xOffset = width / 4;
1083 deUint32 yOffset = height / 4;
1084 if (m_params.tessShader)
1085 xOffset /= 2;
1086 if (m_params.geomShader)
1087 yOffset /= 2;
1088
1089 bool inside = false;
1090 if (m_params.lines)
1091 {
1092 if (m_params.stippledLineEnable)
1093 {
1094 if (m_params.tessShader && m_params.geomShader)
1095 inside = (j == 4 && i == 3) || (j == 20 && i == 3);
1096 else if (m_params.tessShader)
1097 inside = (j == 8 && i == 3);
1098 else if (m_params.geomShader)
1099 inside = (j == 3 && i == 8) || (j == 27 && i == 8);
1100 else
1101 inside = (j == 7 && i == 8) || (j == 23 && i == 8);
1102 }
1103 else
1104 {
1105 if (m_params.tessShader && m_params.geomShader)
1106 inside = m_params.lines && (i == 3 && (j >= 4 && j < 28));
1107 else if (m_params.tessShader)
1108 inside = m_params.lines && (i == 3 && (j >= 8 && j < 24));
1109 else if (m_params.geomShader)
1110 inside = m_params.lines && ((j == 3 || j == 27) && (i >= 8 && i < 24));
1111 else
1112 inside = m_params.lines && (i >= 8 && i < 24 && (j == 7 || j == 23));
1113 }
1114 }
1115 else
1116 {
1117 inside = !m_params.lines && (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset);
1118 }
1119 return inside;
1120 }
1121
1122 tcu::TestStatus ShaderObjectStateInstance::iterate (void)
1123 {
1124 const vk::VkInstance instance = m_context.getInstance();
1125 const vk::InstanceDriver instanceDriver (m_context.getPlatformInterface(), instance);
1126 createDevice();
1127 const vk::DeviceInterface& vk = *m_logicalDeviceInterface;
1128 const vk::VkDevice device = *m_customDevice;
1129 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1130 const vk::VkQueue queue = m_logicalDeviceQueue;
1131 auto alloctor = de::MovePtr<vk::Allocator>(new vk::SimpleAllocator(vk, device, getPhysicalDeviceMemoryProperties(instanceDriver, m_context.getPhysicalDevice())));
1132 auto& alloc = *alloctor;
1133 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
1134 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
1135 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
1136 tcu::TestLog& log = m_context.getTestContext().getLog();
1137
1138 vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
1139 vk::VkFormat depthStencilAttachmentFormat = findDSFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice());
1140 const auto subresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1141 const auto subresourceLayers = vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
1142 auto depthSubresourceRange = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, 1u);
1143 const vk::VkRect2D renderArea = vk::makeRect2D(0, 0, 32, 32);
1144 vk::VkExtent3D extent = { renderArea.extent.width, renderArea.extent.height, 1};
1145
1146 const bool taskSupported = m_context.getMeshShaderFeatures().taskShader;
1147 const bool meshSupported = m_context.getMeshShaderFeatures().meshShader;
1148
1149 const vk::VkImageCreateInfo createInfo =
1150 {
1151 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
1152 DE_NULL, // const void* pNext
1153 0u, // VkImageCreateFlags flags
1154 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
1155 colorAttachmentFormat, // VkFormat format
1156 { 32, 32, 1 }, // VkExtent3D extent
1157 1u, // uint32_t mipLevels
1158 1u, // uint32_t arrayLayers
1159 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
1160 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
1161 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
1162 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
1163 0, // uint32_t queueFamilyIndexCount
1164 DE_NULL, // const uint32_t* pQueueFamilyIndices
1165 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
1166 };
1167
1168 const vk::VkImageCreateInfo depthCreateInfo =
1169 {
1170 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
1171 DE_NULL, // const void* pNext
1172 0u, // VkImageCreateFlags flags
1173 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
1174 depthStencilAttachmentFormat, // VkFormat format
1175 { 32, 32, 1 }, // VkExtent3D extent
1176 1u, // uint32_t mipLevels
1177 1u, // uint32_t arrayLayers
1178 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
1179 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
1180 vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
1181 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
1182 0, // uint32_t queueFamilyIndexCount
1183 DE_NULL, // const uint32_t* pQueueFamilyIndices
1184 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
1185 };
1186
1187 de::MovePtr<vk::ImageWithMemory> image = de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
1188 const auto imageView = vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
1189
1190 de::MovePtr<vk::ImageWithMemory> depthImage = de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, depthCreateInfo, vk::MemoryRequirement::Any));
1191 const auto depthImageView = vk::makeImageView(vk, device, **depthImage, vk::VK_IMAGE_VIEW_TYPE_2D, depthStencilAttachmentFormat, depthSubresourceRange);
1192
1193 const vk::VkDeviceSize colorOutputBufferSize = renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
1194 de::MovePtr<vk::BufferWithMemory> colorOutputBuffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
1195 vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT), vk::MemoryRequirement::HostVisible));
1196
1197 const vk::Move<vk::VkCommandPool> cmdPool (vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
1198 const vk::Move<vk::VkCommandBuffer> cmdBuffer (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1199
1200 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
1201 vk::DescriptorSetLayoutBuilder()
1202 .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_ALL_GRAPHICS | vk::VK_SHADER_STAGE_MESH_BIT_EXT)
1203 .build(vk, device));
1204
1205 const vk::Unique<vk::VkDescriptorPool> descriptorPool(
1206 vk::DescriptorPoolBuilder()
1207 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
1208 .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
1209
1210 const vk::VkDeviceSize bufferSizeBytes = sizeof(deUint32) * 8;
1211 const vk::Unique<vk::VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
1212 const vk::BufferWithMemory outputBuffer (vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), vk::MemoryRequirement::HostVisible);
1213
1214 const vk::VkDescriptorBufferInfo descriptorInfo = vk::makeDescriptorBufferInfo(*outputBuffer, 0ull, bufferSizeBytes);
1215 vk::DescriptorSetUpdateBuilder()
1216 .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
1217 .update(vk, device);
1218
1219 const auto pipelineLayout = makePipelineLayout(vk, device, *descriptorSetLayout);
1220
1221 const auto& binaries = m_context.getBinaryCollection();
1222 vk::Move<vk::VkPipeline> pipeline;
1223 vk::Move<vk::VkShaderEXT> meshShader;
1224 vk::Move<vk::VkShaderEXT> vertShader;
1225 vk::Move<vk::VkShaderEXT> tescShader;
1226 vk::Move<vk::VkShaderEXT> teseShader;
1227 vk::Move<vk::VkShaderEXT> geomShader;
1228 vk::Move<vk::VkShaderEXT> fragShader;
1229
1230 if (m_params.pipeline)
1231 {
1232 vk::Move<vk::VkShaderModule> meshShaderModule;
1233 vk::Move<vk::VkShaderModule> vertShaderModule;
1234 vk::Move<vk::VkShaderModule> tescShaderModule;
1235 vk::Move<vk::VkShaderModule> teseShaderModule;
1236 vk::Move<vk::VkShaderModule> geomShaderModule;
1237 vk::Move<vk::VkShaderModule> fragShaderModule;
1238 if (m_params.meshShader)
1239 meshShaderModule = vk::createShaderModule(vk, device, binaries.get("mesh"));
1240 if (m_params.vertShader)
1241 vertShaderModule = vk::createShaderModule(vk, device, binaries.get("vert"));
1242 if (m_params.tessShader)
1243 tescShaderModule = vk::createShaderModule(vk, device, binaries.get("tesc"));
1244 if (m_params.tessShader)
1245 teseShaderModule = vk::createShaderModule(vk, device, binaries.get("tese"));
1246 if (m_params.geomShader)
1247 geomShaderModule = vk::createShaderModule(vk, device, binaries.get("geom"));
1248 if (m_params.fragShader)
1249 fragShaderModule = vk::createShaderModule(vk, device, binaries.get("frag"));
1250
1251 const vk::VkPipelineVertexInputStateCreateInfo vertexInputState =
1252 {
1253 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1254 DE_NULL, // const void* pNext;
1255 (vk::VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
1256 0u, // deUint32 vertexBindingDescriptionCount;
1257 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1258 0u, // deUint32 vertexAttributeDescriptionCount;
1259 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1260 };
1261
1262 vk::VkPrimitiveTopology topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
1263 if (m_params.tessShader)
1264 topology = vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
1265 else if (m_params.lines)
1266 topology = vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
1267
1268 const vk::VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
1269 {
1270 vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1271 DE_NULL, // const void* pNext;
1272 (vk::VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
1273 topology, // VkPrimitiveTopology topology;
1274 VK_FALSE // VkBool32 primitiveRestartEnable;
1275 };
1276
1277 const vk::VkPipelineTessellationStateCreateInfo tessellationState =
1278 {
1279 vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
1280 DE_NULL, // const void* pNext;
1281 (vk::VkPipelineTessellationStateCreateFlags)0u, // VkPipelineTessellationStateCreateFlags flags;
1282 4u // deUint32 patchControlPoints;
1283 };
1284
1285 const vk::VkPipelineRasterizationDepthClipStateCreateInfoEXT depthClipState =
1286 {
1287 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT, // VkStructureType sType;
1288 DE_NULL, // const void* pNext;
1289 (vk::VkPipelineRasterizationDepthClipStateCreateFlagsEXT)0u, // VkPipelineRasterizationDepthClipStateCreateFlagsEXT flags;
1290 m_params.depthClip // VkBool32 depthClipEnable;
1291 };
1292
1293 const vk::VkPipelineRasterizationStateCreateInfo rasterizationState =
1294 {
1295 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1296 m_params.depthClip ? &depthClipState : DE_NULL, // const void* pNext;
1297 (vk::VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
1298 m_params.depthClamp, // VkBool32 depthClampEnable;
1299 m_params.rasterizerDiscardEnable, // VkBool32 rasterizerDiscardEnable;
1300 vk::VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
1301 m_params.cull ? (vk::VkCullModeFlags)vk::VK_CULL_MODE_FRONT_AND_BACK : (vk::VkCullModeFlags)vk::VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
1302 vk::VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace;
1303 m_params.depthBiasEnable ? VK_TRUE : VK_FALSE, // VkBool32 depthBiasEnable;
1304 0.0f, // float depthBiasConstantFactor;
1305 0.0f, // float depthBiasClamp;
1306 0.0f, // float depthBiasSlopeFactor;
1307 1.0f // float lineWidth;
1308 };
1309
1310 const vk::VkPipelineMultisampleStateCreateInfo multisampleState =
1311 {
1312 vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType
1313 DE_NULL, // const void* pNext
1314 (vk::VkPipelineMultisampleStateCreateFlags)0u, // VkPipelineMultisampleStateCreateFlags flags
1315 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples
1316 VK_FALSE, // VkBool32 sampleShadingEnable
1317 1.0f, // float minSampleShading
1318 DE_NULL, // const VkSampleMask* pSampleMask
1319 VK_FALSE, // VkBool32 alphaToCoverageEnable
1320 m_params.alphaToOne ? VK_TRUE : VK_FALSE // VkBool32 alphaToOneEnable
1321 };
1322
1323
1324 const vk::VkStencilOpState stencilOpState = vk::makeStencilOpState(
1325 vk::VK_STENCIL_OP_KEEP, // stencil fail
1326 vk::VK_STENCIL_OP_KEEP, // depth & stencil pass
1327 vk::VK_STENCIL_OP_KEEP, // depth only fail
1328 vk::VK_COMPARE_OP_ALWAYS, // compare op
1329 0u, // compare mask
1330 0u, // write mask
1331 0u); // reference
1332
1333 const vk::VkPipelineDepthStencilStateCreateInfo depthStencilState
1334 {
1335 vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
1336 DE_NULL, // const void* pNext
1337 (vk::VkPipelineDepthStencilStateCreateFlags)0u, // VkPipelineDepthStencilStateCreateFlags flags
1338 m_params.depthTestEnable ? VK_TRUE : VK_FALSE, // VkBool32 depthTestEnable
1339 VK_TRUE, // VkBool32 depthWriteEnable
1340 vk::VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp
1341 m_params.depthBoundsTestEnable ? VK_TRUE : VK_FALSE, // VkBool32 depthBoundsTestEnable
1342 m_params.stencilTestEnable ? VK_TRUE : VK_FALSE, // VkBool32 stencilTestEnable
1343 stencilOpState, // VkStencilOpState front
1344 stencilOpState, // VkStencilOpState back
1345 0.0f, // float minDepthBounds
1346 1.0f, // float maxDepthBounds
1347 };
1348
1349 const vk::VkPipelineColorBlendAttachmentState colorBlendAttState =
1350 {
1351 m_params.colorBlendEnable ? VK_TRUE : VK_FALSE, // VkBool32 blendEnable;
1352 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
1353 vk::VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
1354 vk::VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
1355 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
1356 vk::VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
1357 vk::VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
1358 vk::VK_COLOR_COMPONENT_R_BIT | vk::VK_COLOR_COMPONENT_G_BIT |
1359 vk::VK_COLOR_COMPONENT_B_BIT | vk::VK_COLOR_COMPONENT_A_BIT, // VkColorComponentFlags colorWriteMask;
1360 };
1361
1362 const deUint32 colorAttachmentCount = 2;
1363 const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(instanceDriver, m_context.getPhysicalDevice());
1364 std::vector<vk::VkBool32> colorWriteEnables (properties.limits.maxColorAttachments);
1365 for (deUint32 i = 0; i < properties.limits.maxColorAttachments; ++i)
1366 {
1367 colorWriteEnables[i] = i < colorAttachmentCount ? VK_TRUE : VK_FALSE;
1368 }
1369 const vk::VkPipelineColorWriteCreateInfoEXT colorWriteState =
1370 {
1371 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT, // VkStructureType sType;
1372 DE_NULL, // const void* pNext;
1373 (deUint32)colorWriteEnables.size(), // uint32_t attachmentCount;
1374 colorWriteEnables.data() // const VkBool32* pColorWriteEnables;
1375 };
1376
1377 const vk::VkPipelineColorBlendStateCreateInfo colorBlendState =
1378 {
1379 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1380 m_params.colorWrite ? &colorWriteState : DE_NULL, // const void* pNext;
1381 (vk::VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
1382 m_params.logicOpEnable ? VK_TRUE : VK_FALSE, // VkBool32 logicOpEnable;
1383 vk::VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1384 1u, // uint32_t attachmentCount;
1385 &colorBlendAttState, // const VkPipelineColorBlendAttachmentState* pAttachments;
1386 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
1387 };
1388
1389 vk::VkViewport viewport = { 0, 0, 32, 32, 0.0f, 1.0f, };
1390 vk::VkRect2D scissor = { { 0, 0, }, { 32, 32, }, };
1391
1392 const auto& edsFeatures = m_context.getExtendedDynamicStateFeaturesEXT();
1393 deUint32 viewportAndScissorCount = edsFeatures.extendedDynamicState ? 0u : 1u;
1394
1395 const vk::VkPipelineViewportDepthClipControlCreateInfoEXT depthClipControlState =
1396 {
1397 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT, // VkStructureType sType;
1398 DE_NULL, // const void* pNext;
1399 VK_TRUE, // VkBool32 negativeOneToOne;
1400 };
1401
1402 const vk::VkPipelineViewportStateCreateInfo viewportState =
1403 {
1404 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType
1405 m_params.depthClipControl ? &depthClipControlState : DE_NULL, // const void* pNext
1406 (vk::VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags
1407 viewportAndScissorCount, // deUint32 viewportCount
1408 &viewport, // const VkViewport* pViewports
1409 viewportAndScissorCount, // deUint32 scissorCount
1410 &scissor // const VkRect2D* pScissors
1411 };
1412
1413 const auto dynamicStates = getDynamicStates();
1414
1415 const vk::VkPipelineDynamicStateCreateInfo dynamicState =
1416 {
1417 vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType
1418 DE_NULL, // const void* pNext
1419 0u, // VkPipelineDynamicStateCreateFlags flags
1420 (deUint32)dynamicStates.size(), // deUint32 dynamicStateCount
1421 dynamicStates.data(), // const VkDynamicState* pDynamicStates
1422 };
1423
1424 const vk::VkPipelineRenderingCreateInfo pipelineRenderingCreateInfo =
1425 {
1426 vk::VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, // VkStructureType sType
1427 DE_NULL, // const void* pNext
1428 0u, // uint32_t viewMask
1429 1u, // uint32_t colorAttachmentCount
1430 &colorAttachmentFormat, // const VkFormat* pColorAttachmentFormats
1431 depthStencilAttachmentFormat, // VkFormat depthAttachmentFormat
1432 depthStencilAttachmentFormat, // VkFormat stencilAttachmentFormat
1433 };
1434
1435 if (m_params.meshShader)
1436 pipeline = vk::makeGraphicsPipeline(vk, device, *pipelineLayout, VK_NULL_HANDLE, *meshShaderModule, *fragShaderModule, VK_NULL_HANDLE, {}, {}, 0u, &rasterizationState, &multisampleState, &depthStencilState, &colorBlendState, &dynamicState, 0u, &pipelineRenderingCreateInfo);
1437 else
1438 pipeline = vk::makeGraphicsPipeline(vk, device, *pipelineLayout, *vertShaderModule, *tescShaderModule, *teseShaderModule, *geomShaderModule, *fragShaderModule, VK_NULL_HANDLE, 0u, &vertexInputState, &inputAssemblyState, &tessellationState, &viewportState, &rasterizationState, &multisampleState, &depthStencilState, &colorBlendState, &dynamicState, &pipelineRenderingCreateInfo);
1439 }
1440 else
1441 {
1442 if (m_params.meshShader)
1443 {
1444 auto meshShaderCreateInfo = vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_MESH_BIT_EXT, binaries.get("mesh"), tessellationSupported, geometrySupported, &*descriptorSetLayout);
1445 meshShaderCreateInfo.flags = vk::VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT;
1446 meshShader = vk::createShader(vk, device, meshShaderCreateInfo);
1447 }
1448 if (m_params.vertShader)
1449 vertShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("vert"), tessellationSupported, geometrySupported, &*descriptorSetLayout));
1450 if (m_params.tessShader)
1451 tescShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, binaries.get("tesc"), tessellationSupported, geometrySupported, &*descriptorSetLayout));
1452 if (m_params.tessShader)
1453 teseShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, binaries.get("tese"), tessellationSupported, geometrySupported, &*descriptorSetLayout));
1454 if (m_params.geomShader)
1455 geomShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_GEOMETRY_BIT, binaries.get("geom"), tessellationSupported, geometrySupported, &*descriptorSetLayout));
1456 if (m_params.fragShader)
1457 fragShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("frag"), tessellationSupported, geometrySupported, &*descriptorSetLayout));
1458 }
1459
1460 const vk::VkDeviceSize tfBufSize = 4 * sizeof(tcu::Vec4);
1461 const vk::VkBufferCreateInfo tfBufCreateInfo = vk::makeBufferCreateInfo(tfBufSize, vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT | vk::VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
1462 const vk::Move<vk::VkBuffer> tfBuf = createBuffer(vk, device, &tfBufCreateInfo);
1463 const de::MovePtr<vk::Allocation> tfBufAllocation = alloc.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), vk::MemoryRequirement::HostVisible);
1464 const vk::VkMemoryBarrier tfMemoryBarrier = vk::makeMemoryBarrier(vk::VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, vk::VK_ACCESS_HOST_READ_BIT);
1465 vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset());
1466
1467 const vk::VkClearValue clearValue = vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 0.0f });
1468 const vk::VkClearValue clearDepthValue = vk::makeClearValueDepthStencil(1.0f, 0u);
1469 vk::beginCommandBuffer(vk, *cmdBuffer);
1470
1471 vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0, 1, &descriptorSet.get(), 0, DE_NULL);
1472
1473 vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
1474 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &preImageBarrier);
1475
1476 vk::VkImageMemoryBarrier preDepthImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_NONE, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **depthImage, depthSubresourceRange);
1477 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &preDepthImageBarrier);
1478
1479 vk::beginRendering(vk, *cmdBuffer, *imageView, *depthImageView, true, renderArea, clearValue, clearDepthValue, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
1480
1481 if (m_params.pipeline)
1482 {
1483 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1484 }
1485 else
1486 {
1487 if (m_params.meshShader)
1488 {
1489 vk::VkShaderStageFlagBits stages[] = {
1490 vk::VK_SHADER_STAGE_MESH_BIT_EXT,
1491 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
1492 };
1493 vk::VkShaderEXT shaders[] = {
1494 *meshShader,
1495 *fragShader,
1496 };
1497 vk::bindNullRasterizationShaders(vk, *cmdBuffer, m_context.getDeviceFeatures());
1498 vk.cmdBindShadersEXT(*cmdBuffer, 2, stages, shaders);
1499 }
1500 else
1501 {
1502 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, *tescShader, *teseShader, *geomShader, *fragShader, taskSupported, meshSupported);
1503 }
1504 }
1505 setDynamicStates(vk, *cmdBuffer);
1506
1507 if (m_params.geometryStreams)
1508 {
1509 vk::VkDeviceSize offset = 0u;
1510 vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, 1, &*tfBuf, &offset, &tfBufSize);
1511 vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0u, DE_NULL, DE_NULL);
1512 }
1513
1514 bool secondDraw = !m_params.depthClamp && !m_params.depthClip;
1515 if (m_params.meshShader)
1516 {
1517 if (secondDraw)
1518 vk.cmdDrawMeshTasksEXT(*cmdBuffer, 2, 1, 1);
1519 else
1520 vk.cmdDrawMeshTasksEXT(*cmdBuffer, 1, 1, 1);
1521 }
1522 else
1523 {
1524 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
1525 if (secondDraw)
1526 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 1);
1527 }
1528 if (m_params.geometryStreams)
1529 vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0u, DE_NULL, DE_NULL);
1530 vk::endRendering(vk, *cmdBuffer);
1531
1532 vk::VkImageMemoryBarrier postImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
1533 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarrier);
1534
1535 vk::VkImageMemoryBarrier postDepthImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **depthImage, depthSubresourceRange);
1536 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &postDepthImageBarrier);
1537
1538 vk::VkBufferMemoryBarrier bufferBarrier = vk::makeBufferMemoryBarrier(vk::VK_ACCESS_SHADER_WRITE_BIT, vk::VK_ACCESS_HOST_READ_BIT, *outputBuffer, 0u, bufferSizeBytes);
1539 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 1u, &bufferBarrier, 0u, (const vk::VkImageMemoryBarrier*)DE_NULL);
1540
1541 if (m_params.geometryStreams)
1542 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &tfMemoryBarrier, 0u, DE_NULL, 0u, DE_NULL);
1543
1544
1545 const vk::VkBufferImageCopy copyRegion = vk::makeBufferImageCopy(extent, subresourceLayers);
1546 vk.cmdCopyImageToBuffer(*cmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u, ©Region);
1547
1548 vk::endCommandBuffer(vk, *cmdBuffer);
1549 vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1550
1551 tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(vk::mapVkFormat(colorAttachmentFormat), renderArea.extent.width, renderArea.extent.height, 1, (const void*)colorOutputBuffer->getAllocation().getHostPtr());
1552
1553 const deInt32 width = resultBuffer.getWidth();
1554 const deInt32 height = resultBuffer.getHeight();
1555 const float threshold = 1.0f / 256.0f;
1556 tcu::Vec4 whiteColor = tcu::Vec4(0.75f);
1557 tcu::Vec4 blackColor = tcu::Vec4(0.0f);
1558
1559 const vk::Allocation& outputBufferAllocation = outputBuffer.getAllocation();
1560 invalidateAlloc(vk, device, outputBufferAllocation);
1561
1562 const deUint32* bufferPtr = static_cast<deUint32*>(outputBufferAllocation.getHostPtr());
1563
1564 if (m_params.geometryStreams)
1565 {
1566 invalidateAlloc(vk, device, *tfBufAllocation);
1567 const float* tfData = static_cast<float*>(tfBufAllocation->getHostPtr());
1568 deUint32 count = m_params.lines ? 2 : 3;
1569 for (deUint32 i = 0; i < count; ++i)
1570 {
1571 for (deUint32 j = 0; j < 4; ++j)
1572 {
1573 if (tfData[i * 4 + j] != float(i + 1))
1574 {
1575 return tcu::TestStatus::fail("Fail");
1576 }
1577 }
1578 }
1579 return tcu::TestStatus::pass("Pass");
1580 }
1581
1582 if (m_params.vertShader)
1583 {
1584 if (bufferPtr[0] != 1u)
1585 {
1586 log << tcu::TestLog::Message << "Buffer value at index 0 was expected to be 1, but was[" << bufferPtr[0] << tcu::TestLog::EndMessage;
1587 return tcu::TestStatus::fail("Fail");
1588 }
1589 }
1590
1591 if (m_params.tessShader)
1592 {
1593 if (bufferPtr[1] != 2u)
1594 {
1595 log << tcu::TestLog::Message << "Buffer value at index 1 was expected to be 2, but was[" << bufferPtr[1] << tcu::TestLog::EndMessage;
1596 return tcu::TestStatus::fail("Fail");
1597 }
1598 if (bufferPtr[2] != 3u)
1599 {
1600 log << tcu::TestLog::Message << "Buffer value at index 2 was expected to be 3, but was[" << bufferPtr[2] << tcu::TestLog::EndMessage;
1601 return tcu::TestStatus::fail("Fail");
1602 }
1603 }
1604
1605 if (m_params.geomShader)
1606 {
1607 if (bufferPtr[3] != 4u)
1608 {
1609 log << tcu::TestLog::Message << "Buffer value at index 3 was expected to be 4, but was[" << bufferPtr[3] << tcu::TestLog::EndMessage;
1610 return tcu::TestStatus::fail("Fail");
1611 }
1612 }
1613
1614 if (m_params.fragShader && !m_params.rasterizerDiscardEnable)
1615 {
1616 for (deInt32 j = 0; j < height; ++j)
1617 {
1618 for (deInt32 i = 0; i < width; ++i)
1619 {
1620 const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
1621
1622 tcu::Vec4 expectedColor = blackColor;
1623 bool inside = isInsidePrimitive(i, j, width, height);
1624 if (m_params.conservativeRasterization && m_params.conservativeRasterizationOverestimate && !inside)
1625 continue;
1626 if (inside && (!m_params.cull || m_params.lines) && (!m_params.colorWrite || m_params.colorWriteEnable))
1627 {
1628 if (!m_params.depthBoundsTestEnable && (!m_params.depthClip || i < 16) && !m_params.discardRectanglesEnable)
1629 {
1630 expectedColor = whiteColor;
1631 if (m_params.alphaToOne)
1632 expectedColor.w() = 1.0f;
1633 if (m_params.colorBlendEnable && secondDraw && !m_params.logicOpEnable && !m_params.stencilTestEnable)
1634 expectedColor = tcu::Vec4(1.0f);
1635 }
1636 }
1637
1638 if (deFloatAbs(color.x() - expectedColor.x()) > threshold || deFloatAbs(color.y() - expectedColor.y()) > threshold || deFloatAbs(color.z() - expectedColor.z()) > threshold || deFloatAbs(color.w() - expectedColor.w()) > threshold)
1639 {
1640 log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") is expected to be (" << expectedColor << "), but was (" << color << ")" << tcu::TestLog::EndMessage;
1641 return tcu::TestStatus::fail("Fail");
1642 }
1643 }
1644 }
1645 }
1646
1647 if (m_params.fragShader && !m_params.rasterizerDiscardEnable)
1648 {
1649 const auto depthBuffer = readDepthAttachment(vk, device, queue, queueFamilyIndex, alloc, **depthImage, depthStencilAttachmentFormat, tcu::UVec2(width, height), vk::VK_IMAGE_LAYOUT_GENERAL);
1650 const auto depthAccess = depthBuffer->getAccess();
1651 const auto stencilBuffer = readStencilAttachment(vk, device, queue, queueFamilyIndex, alloc, **depthImage, depthStencilAttachmentFormat, tcu::UVec2(width, height), vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1652 const auto stencilAccess = stencilBuffer->getAccess();
1653 const float depthEpsilon = 0.02f;
1654
1655 for (deInt32 j = 0; j < height; ++j)
1656 {
1657 for (deInt32 i = 0; i < width; ++i)
1658 {
1659 const float depth = depthAccess.getPixDepth(i, j);
1660 const int stencil = stencilAccess.getPixStencil(i, j);
1661 bool inside = isInsidePrimitive(i, j, width, height);
1662 if (m_params.conservativeRasterization && m_params.conservativeRasterizationOverestimate && !inside)
1663 continue;
1664 if (inside && !m_params.depthBoundsTestEnable && !m_params.discardRectanglesEnable && (!m_params.cull || m_params.lines))
1665 {
1666 float depthMin = 0.4f - depthEpsilon;
1667 float depthMax = 0.6f + depthEpsilon;
1668 if (m_params.stencilTestEnable)
1669 {
1670 depthMin = 0.7f - depthEpsilon;
1671 depthMax = 0.9f + depthEpsilon;
1672 }
1673 if (m_params.depthClamp)
1674 {
1675 depthMin = 0.35f - depthEpsilon;
1676 depthMax = 0.45f + depthEpsilon;
1677 }
1678 if (m_params.depthClip)
1679 {
1680 depthMin = 0.9f - depthEpsilon;
1681 depthMax = 1.0f + depthEpsilon;
1682 }
1683 if (m_params.depthClipControl)
1684 {
1685 depthMin = 0.7f - depthEpsilon;
1686 depthMax = 1.0f + depthEpsilon;
1687 }
1688 if (m_params.depthBiasEnable)
1689 {
1690 if (m_params.lines)
1691 {
1692 depthMin += 0.004f;
1693 depthMax += 0.004f;
1694 }
1695 else
1696 {
1697 depthMin += 0.03f;
1698 depthMax += 0.03f;
1699 }
1700 }
1701
1702 if (depth < depthMin || depth > depthMax)
1703 {
1704 log << tcu::TestLog::Message << "Depth at (" << i << ", " << j << ") is expected to be between 0.4f and 0.6f, but was (" << depth << ")" << tcu::TestLog::EndMessage;
1705 return tcu::TestStatus::fail("Fail");
1706 }
1707 if (m_params.stencilTestEnable && (!m_params.depthClip || i < 16))
1708 {
1709 if (stencil != 255)
1710 {
1711 log << tcu::TestLog::Message << "Stencil at (" << i << ", " << j << ") is expected to be 0, but was (" << stencil << ")" << tcu::TestLog::EndMessage;
1712 return tcu::TestStatus::fail("Fail");
1713 }
1714 }
1715 }
1716 else
1717 {
1718 if (deFloatAbs(depth - 1.0f) > depthEpsilon)
1719 {
1720 log << tcu::TestLog::Message << "Depth at (" << i << ", " << j << ") is expected to be 1.0f, but was (" << depth << ")" << tcu::TestLog::EndMessage;
1721 return tcu::TestStatus::fail("Fail");
1722 }
1723 if (m_params.stencilTestEnable)
1724 {
1725 if (stencil != 0)
1726 {
1727 log << tcu::TestLog::Message << "Stencil at (" << i << ", " << j << ") is expected to be 1, but was (" << stencil << ")" << tcu::TestLog::EndMessage;
1728 return tcu::TestStatus::fail("Fail");
1729 }
1730 }
1731 }
1732 }
1733 }
1734 }
1735
1736 if (m_params.meshShader)
1737 {
1738 if (bufferPtr[4] != 5u)
1739 {
1740 log << tcu::TestLog::Message << "Buffer value at index 5 was expected to be 6, but was[" << bufferPtr[5] << tcu::TestLog::EndMessage;
1741 return tcu::TestStatus::fail("Fail");
1742 }
1743 }
1744
1745 return tcu::TestStatus::pass("Pass");
1746 }
1747
1748 class ShaderObjectStateCase : public vkt::TestCase
1749 {
1750 public:
1751 ShaderObjectStateCase (tcu::TestContext& testCtx, const std::string& name, const StateTestParams& testParams)
1752 : vkt::TestCase (testCtx, name)
1753 , m_params (testParams)
1754 {}
1755 virtual ~ShaderObjectStateCase (void) {}
1756
1757 void checkSupport (vkt::Context& context) const override;
1758 virtual void initPrograms (vk::SourceCollections& programCollection) const override;
1759 TestInstance* createInstance (Context& context) const override { return new ShaderObjectStateInstance(context, m_params); }
1760
1761 const StateTestParams m_params;
1762 };
1763
1764 void ShaderObjectStateCase::checkSupport (Context& context) const
1765 {
1766 const auto& edsFeatures = context.getExtendedDynamicStateFeaturesEXT();
1767 const auto& eds2Features = context.getExtendedDynamicState2FeaturesEXT();
1768 const auto& eds3Features = context.getExtendedDynamicState3FeaturesEXT();
1769
1770 const auto& vki = context.getInstanceInterface();
1771 const auto physicalDevice = context.getPhysicalDevice();
1772 if (findDSFormat(vki, physicalDevice) == vk::VK_FORMAT_UNDEFINED)
1773 TCU_THROW(NotSupportedError, "Required depth/stencil format not supported");
1774
1775 if (!m_params.pipeline)
1776 context.requireDeviceFunctionality("VK_EXT_shader_object");
1777 else
1778 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
1779
1780 if (m_params.logicOp)
1781 {
1782 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LOGIC_OP);
1783 if (m_params.pipeline && !eds2Features.extendedDynamicState2LogicOp)
1784 TCU_THROW(NotSupportedError, "extendedDynamicState2LogicOp not supported");
1785 }
1786 if (m_params.alphaToOne)
1787 {
1788 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_ALPHA_TO_ONE);
1789 if (m_params.pipeline && !eds3Features.extendedDynamicState3AlphaToOneEnable)
1790 TCU_THROW(NotSupportedError, "extendedDynamicState3AlphaToOneEnable not supported");
1791 }
1792 if (m_params.depthBounds)
1793 {
1794 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_BOUNDS);
1795 if (m_params.pipeline && !edsFeatures.extendedDynamicState)
1796 TCU_THROW(NotSupportedError, "extendedDynamicState not supported");
1797 }
1798 if (m_params.depthClamp)
1799 {
1800 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_CLAMP);
1801 if (m_params.pipeline && !eds3Features.extendedDynamicState3DepthClampEnable)
1802 TCU_THROW(NotSupportedError, "extendedDynamicState3DepthClampEnable not supported");
1803 }
1804 if (m_params.depthClip)
1805 {
1806 context.requireDeviceFunctionality("VK_EXT_depth_clip_enable");
1807 if (!context.getDepthClipEnableFeaturesEXT().depthClipEnable)
1808 TCU_THROW(NotSupportedError, "depthClipEnable not supported");
1809 if (m_params.pipeline && !eds3Features.extendedDynamicState3DepthClipEnable)
1810 TCU_THROW(NotSupportedError, "extendedDynamicState3DepthClipEnable not supported");
1811 }
1812 if (m_params.depthClipControl)
1813 {
1814 context.requireDeviceFunctionality("VK_EXT_depth_clip_control");
1815 if (!context.getDepthClipControlFeaturesEXT().depthClipControl)
1816 TCU_THROW(NotSupportedError, "depthClipControl not supported");
1817 if (m_params.pipeline && !eds3Features.extendedDynamicState3DepthClipNegativeOneToOne)
1818 TCU_THROW(NotSupportedError, "extendedDynamicState3DepthClipNegativeOneToOne not supported");
1819 }
1820 if (m_params.colorWrite)
1821 {
1822 context.requireDeviceFunctionality("VK_EXT_color_write_enable");
1823 if (!context.getColorWriteEnableFeaturesEXT().colorWriteEnable)
1824 TCU_THROW(NotSupportedError, "colorWriteEnable not supported");
1825 }
1826 if (m_params.geometryStreams)
1827 {
1828 context.requireDeviceFunctionality("VK_EXT_transform_feedback");
1829 if (!context.getTransformFeedbackFeaturesEXT().geometryStreams)
1830 TCU_THROW(NotSupportedError, "geometryStreams not supported");
1831 if (m_params.pipeline && !eds3Features.extendedDynamicState3RasterizationStream)
1832 TCU_THROW(NotSupportedError, "extendedDynamicState3RasterizationStream not supported");
1833 }
1834 if (m_params.discardRectangles)
1835 {
1836 context.requireDeviceFunctionality("VK_EXT_discard_rectangles");
1837
1838 deUint32 propertyCount = 0u;
1839 std::vector<vk::VkExtensionProperties> extensionsProperties;
1840 context.getInstanceInterface().enumerateDeviceExtensionProperties(context.getPhysicalDevice(), DE_NULL, &propertyCount, DE_NULL);
1841 extensionsProperties.resize(propertyCount);
1842 context.getInstanceInterface().enumerateDeviceExtensionProperties(context.getPhysicalDevice(), DE_NULL, &propertyCount, extensionsProperties.data());
1843
1844 for (const auto& extProp : extensionsProperties)
1845 {
1846 if (strcmp(extProp.extensionName, "VK_EXT_discard_rectangles") == 0)
1847 {
1848 if (extProp.specVersion < 2)
1849 TCU_THROW(NotSupportedError, "VK_EXT_discard_rectangles is version 1. Needs version 2 or higher");
1850 }
1851 }
1852 }
1853 if (m_params.conservativeRasterization)
1854 {
1855 context.requireDeviceFunctionality("VK_EXT_conservative_rasterization");
1856 if (m_params.pipeline && !eds3Features.extendedDynamicState3ConservativeRasterizationMode)
1857 TCU_THROW(NotSupportedError, "extendedDynamicState3ConservativeRasterizationMode not supported");
1858 }
1859 if (m_params.sampleLocations)
1860 {
1861 context.requireDeviceFunctionality("VK_EXT_sample_locations");
1862 if (m_params.sampleLocationsEnable && (context.getSampleLocationsPropertiesEXT().sampleLocationSampleCounts & vk::VK_SAMPLE_COUNT_1_BIT) == 0)
1863 TCU_THROW(NotSupportedError, "VK_SAMPLE_COUNT_1_BIT not supported in sampleLocationSampleCounts");
1864 }
1865 if (m_params.provokingVertex)
1866 {
1867 context.requireDeviceFunctionality("VK_EXT_provoking_vertex");
1868 if (m_params.pipeline && !eds3Features.extendedDynamicState3ProvokingVertexMode)
1869 TCU_THROW(NotSupportedError, "extendedDynamicState3ProvokingVertexMode not supported");
1870 }
1871 if (m_params.lineRasterization)
1872 {
1873 context.requireDeviceFunctionality("VK_EXT_line_rasterization");
1874 if (!context.getLineRasterizationFeaturesEXT().rectangularLines)
1875 TCU_THROW(NotSupportedError, "rectangularLines not supported");
1876 if (m_params.pipeline && !eds3Features.extendedDynamicState3LineRasterizationMode)
1877 TCU_THROW(NotSupportedError, "extendedDynamicState3LineRasterizationMode not supported");
1878 if (m_params.pipeline && !eds3Features.extendedDynamicState3LineStippleEnable)
1879 TCU_THROW(NotSupportedError, "extendedDynamicState3LineStippleEnable not supported");
1880 if (m_params.stippledLineEnable && !context.getLineRasterizationFeaturesEXT().stippledRectangularLines)
1881 TCU_THROW(NotSupportedError, "stippledRectangularLines not supported");
1882 }
1883 if (m_params.geomShader)
1884 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
1885 if (m_params.tessShader)
1886 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
1887 if (m_params.meshShader)
1888 {
1889 context.requireDeviceFunctionality("VK_EXT_mesh_shader");
1890 if (!context.getMeshShaderFeaturesEXT().meshShader)
1891 TCU_THROW(NotSupportedError, "Mesh shaders not supported");
1892 }
1893 if (m_params.lines)
1894 {
1895 if (m_params.pipeline && !edsFeatures.extendedDynamicState)
1896 TCU_THROW(NotSupportedError, "extendedDynamicState not supported");
1897 }
1898 if (m_params.colorBlendEnable && m_params.pipeline)
1899 {
1900 context.requireDeviceFunctionality("VK_EXT_extended_dynamic_state3");
1901 if (!eds3Features.extendedDynamicState3ColorBlendEnable)
1902 TCU_THROW(NotSupportedError, "extendedDynamicState3ColorBlendEnable not supported");
1903 }
1904 }
1905
1906 void ShaderObjectStateCase::initPrograms (vk::SourceCollections& programCollection) const
1907 {
1908 std::stringstream vert;
1909 std::stringstream geom;
1910 std::stringstream tesc;
1911 std::stringstream tese;
1912 std::stringstream frag;
1913
1914 vert
1915 << "#version 450\n"
1916 << "layout(binding = 0) buffer Output {\n"
1917 << " uint values[8];\n"
1918 << "} buffer_out;\n\n"
1919 << "void main() {\n"
1920 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1)) - vec2(0.0001f);\n";
1921 if (m_params.depthClip)
1922 vert << " float z = 0.9f;\n";
1923 else
1924 vert << " float z = 0.7f;\n";
1925 vert << " if ((gl_VertexIndex & 1) > 0)\n"
1926 << " z += 0.2f;\n"
1927 << " if ((gl_InstanceIndex & 1) > 0)\n"
1928 << " z -= 0.3f;\n"
1929 << " gl_Position = vec4(pos - 0.5f, z, 1.0f);\n"
1930 << " if (gl_VertexIndex == 0)\n"
1931 << " buffer_out.values[0] = 1u;\n"
1932 << "}\n";
1933
1934 tesc
1935 << "#version 450\n"
1936 << "layout(vertices = 4) out;\n"
1937 << "layout(binding = 0) buffer Output {\n"
1938 << " uint values[8];\n"
1939 << "} buffer_out;\n\n"
1940 << "void main (void)\n"
1941 << "{\n"
1942 << " if (gl_InvocationID == 0) {\n"
1943 << " gl_TessLevelInner[0] = 1.0;\n"
1944 << " gl_TessLevelInner[1] = 1.0;\n"
1945 << " gl_TessLevelOuter[0] = 1.0;\n"
1946 << " gl_TessLevelOuter[1] = 1.0;\n"
1947 << " gl_TessLevelOuter[2] = 1.0;\n"
1948 << " gl_TessLevelOuter[3] = 1.0;\n"
1949 << " buffer_out.values[1] = 2u;\n"
1950 << " }\n"
1951 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1952 << "}\n";
1953
1954 tese
1955 << "#version 450\n";
1956 if (m_params.lines)
1957 tese << "layout(isolines, equal_spacing) in;\n";
1958 else
1959 tese << "layout(quads, equal_spacing) in;\n";
1960 tese << "layout(binding = 0) buffer Output {\n"
1961 << " uint values[8];\n"
1962 << "} buffer_out;\n\n"
1963 << "void main (void)\n"
1964 << "{\n"
1965 << " float u = gl_TessCoord.x;\n"
1966 << " float v = gl_TessCoord.y;\n"
1967 << " float omu = 1.0f - u;\n"
1968 << " float omv = 1.0f - v;\n"
1969 << " gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
1970 << " gl_Position.x *= 1.5f;\n"
1971 << " if (gl_PrimitiveID == 0u)\n"
1972 << " buffer_out.values[2] = 3u;\n"
1973 << "}\n";
1974
1975 geom
1976 << "#version 450\n";
1977 if (m_params.lines)
1978 geom << "layout(lines) in;\n";
1979 else
1980 geom << "layout(triangles) in;\n";
1981 if (m_params.lines)
1982 geom << "layout(line_strip, max_vertices = 4) out;\n";
1983 else
1984 geom << "layout(triangle_strip, max_vertices = 4) out;\n";
1985 if (m_params.geometryStreams)
1986 geom << "layout(stream = 0, xfb_buffer = 0, xfb_offset = 0, xfb_stride = 16, location = 0) out vec4 out0;\n";
1987 geom << "layout(binding = 0) buffer Output {\n"
1988 << " uint values[8];\n"
1989 << "} buffer_out;\n\n"
1990 << "void main(void)\n"
1991 << "{\n"
1992 << " gl_Position = gl_in[0].gl_Position;\n"
1993 << " gl_Position.y *= 1.5f;\n";
1994 if (m_params.geometryStreams)
1995 geom << " out0 = vec4(1.0f);\n"
1996 << " EmitStreamVertex(0);\n";
1997 else
1998 geom << " EmitVertex();\n";
1999 geom << " gl_Position = gl_in[1].gl_Position;\n"
2000 << " gl_Position.y *= 1.5f;\n";
2001 if (m_params.geometryStreams)
2002 geom << " out0 = vec4(2.0f);\n"
2003 << " EmitStreamVertex(0);\n";
2004 else
2005 geom << " EmitVertex();\n";
2006 if (!m_params.lines)
2007 {
2008 geom << " gl_Position = gl_in[2].gl_Position;\n"
2009 << " gl_Position.y *= 1.5f;\n";
2010 if (m_params.geometryStreams)
2011 geom << " out0 = vec4(3.0f);\n"
2012 << " EmitStreamVertex(0);\n";
2013 else
2014 geom << " EmitVertex();\n";
2015 }
2016 if (m_params.geometryStreams)
2017 geom << " EndStreamPrimitive(0);\n";
2018 else
2019 geom << " EndPrimitive();\n";
2020 geom << " buffer_out.values[3] = 4u;\n";
2021 geom << "}\n";
2022
2023 frag
2024 << "#version 450\n"
2025 << "layout (location=0) out vec4 outColor;\n"
2026 << "void main() {\n"
2027 << " outColor = vec4(0.75f);\n"
2028 << "}\n";
2029
2030 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
2031 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
2032 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
2033 programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
2034 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
2035
2036 if (m_params.meshShader)
2037 {
2038 std::stringstream mesh;
2039
2040 mesh
2041 << "#version 460\n"
2042 << "#extension GL_EXT_mesh_shader : require\n"
2043 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
2044 << "layout(max_vertices = 4) out;\n"
2045 << "layout(max_primitives = 2) out;\n";
2046 if (m_params.lines)
2047 mesh << "layout(lines) out;\n";
2048 else
2049 mesh << "layout(triangles) out;\n";
2050 mesh
2051 << "layout(binding = 0) buffer Output {\n"
2052 << " uint values[8];\n"
2053 << "} buffer_out;\n\n"
2054 << "void main() {\n"
2055 << " SetMeshOutputsEXT(4u, 2u);\n";
2056 if (m_params.depthClip)
2057 mesh << " float z = 0.9f;\n";
2058 else
2059 mesh << " float z = 0.7f;\n";
2060 mesh
2061 << " if (gl_GlobalInvocationID.x == 1) z -= 0.3f;\n"
2062 << " gl_MeshVerticesEXT[0].gl_Position = vec4(-0.5f, -0.5f, z, 1.0f);\n"
2063 << " gl_MeshVerticesEXT[1].gl_Position = vec4(-0.5f, 0.5f, z, 1.0f);\n"
2064 << " gl_MeshVerticesEXT[2].gl_Position = vec4(0.5f, -0.5f, z + 0.2f, 1.0f);\n"
2065 << " gl_MeshVerticesEXT[3].gl_Position = vec4(0.5f, 0.5f, z + 0.2f, 1.0f);\n";
2066 if (m_params.lines)
2067 mesh << " gl_PrimitiveLineIndicesEXT[0] = uvec2(0u, 2u);\n"
2068 << " gl_PrimitiveLineIndicesEXT[1] = uvec2(1u, 3u);\n";
2069 else
2070 mesh << " gl_PrimitiveTriangleIndicesEXT[0] = uvec3(0u, 1u, 2u);\n"
2071 << " gl_PrimitiveTriangleIndicesEXT[1] = uvec3(1u, 3u, 2u);\n";
2072 mesh
2073 << " buffer_out.values[4] = 5u;\n"
2074 << "}\n";
2075
2076 programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
2077 }
2078 }
2079
2080 struct UnusedBuiltinParams
2081 {
2082 bool linked;
2083 vk::VkShaderStageFlagBits stage;
2084 bool builtin;
2085 };
2086
2087 enum TessellationSpacing
2088 {
2089 EQUAL,
2090 EVEN,
2091 ODD,
2092 };
2093
2094 struct TessellationModesParams
2095 {
2096 deUint32 subdivision;
2097 TessellationSpacing spacing;
2098 };
2099
2100 class ShaderObjectUnusedBuiltinInstance : public vkt::TestInstance
2101 {
2102 public:
2103 ShaderObjectUnusedBuiltinInstance (Context& context, const UnusedBuiltinParams& params)
2104 : vkt::TestInstance (context)
2105 , m_params (params)
2106 {}
2107 virtual ~ShaderObjectUnusedBuiltinInstance (void) {}
2108
2109 tcu::TestStatus iterate (void) override;
2110 private:
2111 UnusedBuiltinParams m_params;
2112 };
2113
2114 tcu::TestStatus ShaderObjectUnusedBuiltinInstance::iterate (void)
2115 {
2116 const vk::VkInstance instance = m_context.getInstance();
2117 const vk::InstanceDriver instanceDriver (m_context.getPlatformInterface(), instance);
2118 const vk::DeviceInterface& vk = m_context.getDeviceInterface();
2119 const vk::VkDevice device = m_context.getDevice();
2120 const vk::VkQueue queue = m_context.getUniversalQueue();
2121 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2122 auto& alloc = m_context.getDefaultAllocator();
2123 tcu::TestLog& log = m_context.getTestContext().getLog();
2124 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
2125 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
2126 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
2127 const bool taskSupported = m_context.getMeshShaderFeatures().taskShader;
2128 const bool meshSupported = m_context.getMeshShaderFeatures().meshShader;
2129
2130 vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
2131 const auto subresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2132 const auto subresourceLayers = vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
2133 const vk::VkRect2D renderArea = vk::makeRect2D(0, 0, 32, 32);
2134 vk::VkExtent3D extent = { renderArea.extent.width, renderArea.extent.height, 1};
2135
2136 const vk::VkImageCreateInfo createInfo =
2137 {
2138 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
2139 DE_NULL, // const void* pNext
2140 0u, // VkImageCreateFlags flags
2141 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
2142 colorAttachmentFormat, // VkFormat format
2143 { 32, 32, 1 }, // VkExtent3D extent
2144 1u, // uint32_t mipLevels
2145 1u, // uint32_t arrayLayers
2146 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
2147 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
2148 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
2149 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
2150 0, // uint32_t queueFamilyIndexCount
2151 DE_NULL, // const uint32_t* pQueueFamilyIndices
2152 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
2153 };
2154
2155 de::MovePtr<vk::ImageWithMemory> image = de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
2156 const auto imageView = vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
2157
2158 const vk::VkDeviceSize colorOutputBufferSize = renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
2159 de::MovePtr<vk::BufferWithMemory> colorOutputBuffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
2160 vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT), vk::MemoryRequirement::HostVisible));
2161
2162 const auto& binaries = m_context.getBinaryCollection();
2163 vk::VkShaderEXT shaders[5];
2164
2165 vk::VkShaderCreateInfoEXT shaderCreateInfos[5]
2166 {
2167 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("vert"), tessellationSupported, geometrySupported),
2168 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, binaries.get("tesc"), tessellationSupported, geometrySupported),
2169 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, binaries.get("tese"), tessellationSupported, geometrySupported),
2170 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_GEOMETRY_BIT, binaries.get("geom"), tessellationSupported, geometrySupported),
2171 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("frag"), tessellationSupported, geometrySupported),
2172 };
2173
2174 vk.createShadersEXT(device, 5u, shaderCreateInfos, DE_NULL, shaders);
2175
2176 if (m_params.linked)
2177 for (auto& ci : shaderCreateInfos)
2178 ci.flags |= vk::VK_SHADER_CREATE_LINK_STAGE_BIT_EXT;
2179
2180 const vk::Move<vk::VkCommandPool> cmdPool (vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
2181 const vk::Move<vk::VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2182
2183 vk::beginCommandBuffer(vk, *cmdBuffer);
2184
2185 vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
2186 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &preImageBarrier);
2187
2188 const vk::VkClearValue clearValue = vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 0.0f });
2189 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
2190
2191 vk::bindGraphicsShaders(vk, *cmdBuffer, shaders[0], shaders[1], shaders[2], shaders[3], shaders[4], taskSupported, meshSupported);
2192 vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
2193
2194 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
2195
2196 vk::endRendering(vk, *cmdBuffer);
2197
2198 vk::VkImageMemoryBarrier postImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
2199 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarrier);
2200
2201 const vk::VkBufferImageCopy copyRegion = vk::makeBufferImageCopy(extent, subresourceLayers);
2202 vk.cmdCopyImageToBuffer(*cmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u, ©Region);
2203
2204 vk::endCommandBuffer(vk, *cmdBuffer);
2205 vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
2206
2207 for (deUint32 i = 0u; i < 5u; ++i)
2208 vk.destroyShaderEXT(device, shaders[i], DE_NULL);
2209
2210 tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(vk::mapVkFormat(colorAttachmentFormat), renderArea.extent.width, renderArea.extent.height, 1, (const void*)colorOutputBuffer->getAllocation().getHostPtr());
2211
2212 const tcu::Vec4 black = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
2213 const tcu::Vec4 white = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
2214 const deUint32 width = resultBuffer.getWidth();
2215 const deUint32 height = resultBuffer.getHeight();
2216 const deUint32 xOffset = 4u;
2217 const deUint32 yOffset = 4u;
2218
2219 for (deUint32 j = 0; j < height; ++j)
2220 {
2221 for (deUint32 i = 0; i < width; ++i)
2222 {
2223 const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
2224 if (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset)
2225 {
2226 if (color != white)
2227 {
2228 log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") is expected to be (1.0, 1.0, 1.0, 1.0), but was (" << color << ")" << tcu::TestLog::EndMessage;
2229 return tcu::TestStatus::fail("Fail");
2230 }
2231 }
2232 else
2233 {
2234 if (color != black)
2235 {
2236 log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") is expected to be (0.0, 0.0, 0.0, 0.0), but was (" << color << ")" << tcu::TestLog::EndMessage;
2237 return tcu::TestStatus::fail("Fail");
2238 }
2239 }
2240 }
2241 }
2242
2243 return tcu::TestStatus::pass("Pass");
2244 }
2245
2246 class ShaderObjectUnusedBuiltinCase : public vkt::TestCase
2247 {
2248 public:
2249 ShaderObjectUnusedBuiltinCase (tcu::TestContext& testCtx, const std::string& name, const UnusedBuiltinParams& testParams)
2250 : vkt::TestCase (testCtx, name)
2251 , m_params (testParams)
2252 {}
2253 virtual ~ShaderObjectUnusedBuiltinCase (void) {}
2254
2255 void checkSupport (vkt::Context& context) const override;
2256 virtual void initPrograms (vk::SourceCollections& programCollection) const override;
2257 TestInstance* createInstance (Context& context) const override { return new ShaderObjectUnusedBuiltinInstance(context, m_params); }
2258 private:
2259 const UnusedBuiltinParams m_params;
2260 };
2261
2262 void ShaderObjectUnusedBuiltinCase::checkSupport (vkt::Context& context) const
2263 {
2264 context.requireDeviceFunctionality("VK_EXT_shader_object");
2265 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
2266 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
2267 }
2268
2269 void ShaderObjectUnusedBuiltinCase::initPrograms (vk::SourceCollections& programCollection) const
2270 {
2271 std::stringstream vert;
2272 std::stringstream geom;
2273 std::stringstream tesc;
2274 std::stringstream tese;
2275 std::stringstream frag;
2276
2277 vert
2278 << "#version 450\n";
2279 if (m_params.stage == vk::VK_SHADER_STAGE_VERTEX_BIT && !m_params.builtin)
2280 vert << "layout(location = 0) out vec4 unused;\n";
2281 vert
2282 << "void main() {\n"
2283 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
2284 << " gl_Position = vec4(pos - 0.5f, 0.0f, 1.0f);\n";
2285 if (m_params.stage == vk::VK_SHADER_STAGE_VERTEX_BIT)
2286 {
2287 if (m_params.builtin)
2288 {
2289 vert << " gl_PointSize = 16.0f;\n";
2290 vert << " gl_ClipDistance[0] = 2.0f;\n";
2291 }
2292 else
2293 {
2294 vert << " unused = vec4(1.0f);\n";
2295 }
2296 }
2297 vert << "}\n";
2298
2299 tesc
2300 << "#version 450\n"
2301 << "\n"
2302 << "layout(vertices = 4) out;\n";
2303 if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT && !m_params.builtin)
2304 tesc << "layout(location = 0) out vec4 unused[];\n";
2305 tesc << "\n"
2306 << "void main (void)\n"
2307 << "{\n"
2308 << " if (gl_InvocationID == 0) {\n"
2309 << " gl_TessLevelInner[0] = 1.0;\n"
2310 << " gl_TessLevelInner[1] = 1.0;\n"
2311 << " gl_TessLevelOuter[0] = 1.0;\n"
2312 << " gl_TessLevelOuter[1] = 1.0;\n"
2313 << " gl_TessLevelOuter[2] = 1.0;\n"
2314 << " gl_TessLevelOuter[3] = 1.0;\n"
2315 << " }\n"
2316 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n";
2317 if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2318 {
2319 if (m_params.builtin)
2320 {
2321 tesc << " gl_out[gl_InvocationID].gl_PointSize = 16.0f;\n";
2322 tesc << " gl_out[gl_InvocationID].gl_ClipDistance[0] = 2.0f;\n";
2323 }
2324 else
2325 {
2326 tesc << " unused[gl_InvocationID] = vec4(1.0f);\n";
2327 }
2328 }
2329 tesc << "}\n";
2330
2331 tese
2332 << "#version 450\n"
2333 << "\n"
2334 << "layout(quads, equal_spacing) in;\n";
2335 if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT && !m_params.builtin)
2336 tese << "layout(location = 0) out vec4 unused;\n";
2337 tese << "\n"
2338 << "void main (void)\n"
2339 << "{\n"
2340 << " float u = gl_TessCoord.x;\n"
2341 << " float v = gl_TessCoord.y;\n"
2342 << " float omu = 1.0f - u;\n"
2343 << " float omv = 1.0f - v;\n"
2344 << " gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
2345 << " gl_Position.x *= 1.5f;\n";
2346 if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2347 {
2348 if (m_params.builtin)
2349 {
2350 tese << " gl_PointSize = 16.0f;\n";
2351 tese << " gl_ClipDistance[0] = 2.0f;\n";
2352 }
2353 else
2354 {
2355 tese << " unused = vec4(1.0f);\n";
2356 }
2357 }
2358 tese << "}\n";
2359
2360 geom
2361 << "#version 450\n"
2362 << "layout(triangles) in;\n"
2363 << "layout(triangle_strip, max_vertices = 4) out;\n";
2364 if (m_params.stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT && !m_params.builtin)
2365 geom << "layout(location = 0) out vec4 unused;\n";
2366 geom << "\n"
2367 << "void main(void)\n"
2368 << "{\n"
2369 << " gl_Position = gl_in[0].gl_Position;\n"
2370 << " gl_Position.y *= 1.5f;\n"
2371 << " gl_Position.z = 0.5f;\n"
2372 << " EmitVertex();\n"
2373 << " gl_Position = gl_in[1].gl_Position;\n"
2374 << " gl_Position.y *= 1.5f;\n"
2375 << " gl_Position.z = 0.5f;\n"
2376 << " EmitVertex();\n"
2377 << " gl_Position = gl_in[2].gl_Position;\n"
2378 << " gl_Position.y *= 1.5f;\n"
2379 << " gl_Position.z = 0.5f;\n"
2380 << " EmitVertex();\n"
2381 << " EndPrimitive();\n";
2382 if (m_params.stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2383 {
2384 if (m_params.builtin)
2385 geom << " gl_PointSize = 16.0f;\n";
2386 else
2387 geom << " unused = vec4(1.0f);\n";
2388 }
2389 geom << "}\n";
2390
2391 frag
2392 << "#version 450\n"
2393 << "layout (location=0) out vec4 outColor;\n"
2394 << "void main() {\n"
2395 << " outColor = vec4(1.0f);\n"
2396 << "}\n";
2397
2398 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
2399 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
2400 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
2401 programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
2402 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
2403 }
2404
2405 class ShaderObjectTessellationModesInstance : public vkt::TestInstance
2406 {
2407 public:
2408 ShaderObjectTessellationModesInstance (Context& context, const TessellationModesParams& params)
2409 : vkt::TestInstance (context)
2410 , m_params (params)
2411 {}
2412 virtual ~ShaderObjectTessellationModesInstance (void) {}
2413
2414 tcu::TestStatus iterate (void) override;
2415 private:
2416 TessellationModesParams m_params;
2417 };
2418
2419 tcu::TestStatus ShaderObjectTessellationModesInstance::iterate (void)
2420 {
2421 const vk::VkInstance instance = m_context.getInstance();
2422 const vk::InstanceDriver instanceDriver (m_context.getPlatformInterface(), instance);
2423 const vk::DeviceInterface& vk = m_context.getDeviceInterface();
2424 const vk::VkDevice device = m_context.getDevice();
2425 const vk::VkQueue queue = m_context.getUniversalQueue();
2426 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2427 auto& alloc = m_context.getDefaultAllocator();
2428 tcu::TestLog& log = m_context.getTestContext().getLog();
2429 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
2430 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
2431 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
2432 const bool taskSupported = m_context.getMeshShaderFeatures().taskShader;
2433 const bool meshSupported = m_context.getMeshShaderFeatures().meshShader;
2434
2435 vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
2436 const auto subresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2437 const auto subresourceLayers = vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
2438 const vk::VkRect2D renderArea = vk::makeRect2D(0, 0, 32, 32);
2439 vk::VkExtent3D extent = { renderArea.extent.width, renderArea.extent.height, 1};
2440
2441 const vk::VkImageCreateInfo createInfo =
2442 {
2443 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
2444 DE_NULL, // const void* pNext
2445 0u, // VkImageCreateFlags flags
2446 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
2447 colorAttachmentFormat, // VkFormat format
2448 { 32, 32, 1 }, // VkExtent3D extent
2449 1u, // uint32_t mipLevels
2450 1u, // uint32_t arrayLayers
2451 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
2452 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
2453 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
2454 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
2455 0, // uint32_t queueFamilyIndexCount
2456 DE_NULL, // const uint32_t* pQueueFamilyIndices
2457 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
2458 };
2459
2460 de::MovePtr<vk::ImageWithMemory> image = de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
2461 const auto imageView = vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
2462
2463 const vk::VkDeviceSize colorOutputBufferSize = renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
2464 de::MovePtr<vk::BufferWithMemory> colorOutputBuffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
2465 vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT), vk::MemoryRequirement::HostVisible));
2466
2467 const auto& binaries = m_context.getBinaryCollection();
2468 const auto vertShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("vert"), tessellationSupported, geometrySupported));
2469 const auto tescShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, binaries.get("tesc"), tessellationSupported, geometrySupported));
2470 const auto teseShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, binaries.get("tese"), tessellationSupported, geometrySupported));
2471 const auto fragShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("frag"), tessellationSupported, geometrySupported));
2472
2473 const vk::Move<vk::VkCommandPool> cmdPool (vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
2474 const vk::Move<vk::VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2475
2476 vk::beginCommandBuffer(vk, *cmdBuffer);
2477
2478 vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
2479 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &preImageBarrier);
2480
2481 const vk::VkClearValue clearValue = vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 0.0f });
2482 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
2483
2484 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, *tescShader, *teseShader, VK_NULL_HANDLE, *fragShader, taskSupported, meshSupported);
2485 vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
2486
2487 vk.cmdSetPolygonModeEXT(*cmdBuffer, vk::VK_POLYGON_MODE_LINE);
2488
2489 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
2490
2491 vk::endRendering(vk, *cmdBuffer);
2492
2493 vk::VkImageMemoryBarrier postImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
2494 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarrier);
2495
2496 const vk::VkBufferImageCopy copyRegion = vk::makeBufferImageCopy(extent, subresourceLayers);
2497 vk.cmdCopyImageToBuffer(*cmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u, ©Region);
2498
2499 vk::endCommandBuffer(vk, *cmdBuffer);
2500 vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
2501
2502 tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(vk::mapVkFormat(colorAttachmentFormat), renderArea.extent.width, renderArea.extent.height, 1, (const void*)colorOutputBuffer->getAllocation().getHostPtr());
2503
2504 const tcu::Vec4 black = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
2505 const tcu::Vec4 white = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
2506 const deUint32 width = resultBuffer.getWidth();
2507 const deUint32 height = resultBuffer.getHeight();
2508
2509 const bool equal1[17][17] =
2510 {
2511 { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
2512 { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
2513 { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, },
2514 { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, },
2515 { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, },
2516 { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, },
2517 { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, },
2518 { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, },
2519 { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, },
2520 { 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, },
2521 { 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
2522 { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
2523 { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
2524 { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
2525 { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
2526 { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, },
2527 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
2528 };
2529
2530 const bool even1[17][17] =
2531 {
2532 { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
2533 { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, },
2534 { 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, },
2535 { 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, },
2536 { 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, },
2537 { 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, },
2538 { 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, },
2539 { 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, },
2540 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
2541 { 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, },
2542 { 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, },
2543 { 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, },
2544 { 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, },
2545 { 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, },
2546 { 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, },
2547 { 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, },
2548 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
2549 };
2550
2551 const bool odd2[17][17] =
2552 {
2553 { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
2554 { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, },
2555 { 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, },
2556 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
2557 { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, },
2558 { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, },
2559 { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, },
2560 { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, },
2561 { 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, },
2562 { 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, },
2563 { 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, },
2564 { 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, },
2565 { 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, },
2566 { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, },
2567 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
2568 { 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, },
2569 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
2570 };
2571
2572 for (deUint32 j = 0; j < height; ++j)
2573 {
2574 for (deUint32 i = 0; i < width; ++i)
2575 {
2576 const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
2577
2578 bool inside = false;
2579 if (i >= 7 && i < 24 && j >= 7 && j < 24)
2580 {
2581 if ((m_params.subdivision == 1 && m_params.spacing == EQUAL) || (m_params.subdivision == 1 && m_params.spacing == ODD))
2582 inside |= equal1[j - 7][i - 7];
2583 else if ((m_params.subdivision == 1 && m_params.spacing == EVEN) || (m_params.subdivision == 2 && m_params.spacing == EQUAL) || (m_params.subdivision == 2 && m_params.spacing == EVEN))
2584 inside |= even1[j - 7][i - 7];
2585 else if (m_params.subdivision == 2 && m_params.spacing == ODD)
2586 inside |= odd2[j - 7][i - 7];
2587 }
2588
2589 if (inside)
2590 {
2591 if (color != white)
2592 {
2593 log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") is expected to be (1.0, 1.0, 1.0, 1.0), but was (" << color << ")" << tcu::TestLog::EndMessage;
2594 return tcu::TestStatus::fail("Fail");
2595 }
2596 }
2597 else
2598 {
2599 if (color != black)
2600 {
2601 log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") is expected to be (0.0, 0.0, 0.0, 0.0), but was (" << color << ")" << tcu::TestLog::EndMessage;
2602 return tcu::TestStatus::fail("Fail");
2603 }
2604 }
2605 }
2606 }
2607
2608 return tcu::TestStatus::pass("Pass");
2609 }
2610
2611 class ShaderObjectTessellationModesCase : public vkt::TestCase
2612 {
2613 public:
2614 ShaderObjectTessellationModesCase (tcu::TestContext& testCtx, const std::string& name, const TessellationModesParams& testParams)
2615 : vkt::TestCase (testCtx, name)
2616 , m_params (testParams)
2617 {}
2618 virtual ~ShaderObjectTessellationModesCase (void) {}
2619
2620 void checkSupport (vkt::Context& context) const override;
2621 virtual void initPrograms (vk::SourceCollections& programCollection) const override;
2622 TestInstance* createInstance (Context& context) const override { return new ShaderObjectTessellationModesInstance(context, m_params); }
2623 private:
2624 const TessellationModesParams m_params;
2625 };
2626
2627 void ShaderObjectTessellationModesCase::checkSupport (vkt::Context& context) const
2628 {
2629 context.requireDeviceFunctionality("VK_EXT_shader_object");
2630 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
2631 }
2632
2633 void ShaderObjectTessellationModesCase::initPrograms (vk::SourceCollections& programCollection) const
2634 {
2635 std::stringstream vert;
2636 std::stringstream tesc;
2637 std::stringstream tese;
2638 std::stringstream frag;
2639
2640 vert
2641 << "#version 450\n"
2642 << "void main() {\n"
2643 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
2644 << " gl_Position = vec4(pos - 0.5f, 0.0f, 1.0f);\n"
2645 << "}\n";
2646
2647 tesc
2648 << "#version 450\n"
2649 << "\n"
2650 << "layout(vertices = 4) out;\n"
2651 << "\n"
2652 << "void main (void)\n"
2653 << "{\n"
2654 << " if (gl_InvocationID == 0) {\n";
2655 if (m_params.subdivision == 1)
2656 tesc << " float subdivision = 1.0f;\n";
2657 else
2658 tesc << " float subdivision = 2.0f;\n";
2659 tesc
2660 << " gl_TessLevelInner[0] = subdivision;\n"
2661 << " gl_TessLevelInner[1] = subdivision;\n"
2662 << " gl_TessLevelOuter[0] = subdivision;\n"
2663 << " gl_TessLevelOuter[1] = subdivision;\n"
2664 << " gl_TessLevelOuter[2] = subdivision;\n"
2665 << " gl_TessLevelOuter[3] = subdivision;\n"
2666 << " }\n"
2667 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
2668 << "}\n";
2669
2670 tese
2671 << "#version 450\n"
2672 << "\n";
2673 if (m_params.spacing == EQUAL)
2674 tese << "layout(quads, equal_spacing) in;\n";
2675 else if (m_params.spacing == EVEN)
2676 tese << "layout(quads, fractional_even_spacing) in;\n";
2677 else
2678 tese << "layout(quads, fractional_odd_spacing) in;\n";
2679 tese
2680 << "\n"
2681 << "void main (void)\n"
2682 << "{\n"
2683 << " float u = gl_TessCoord.x;\n"
2684 << " float v = gl_TessCoord.y;\n"
2685 << " float omu = 1.0f - u;\n"
2686 << " float omv = 1.0f - v;\n"
2687 << " gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
2688 << "}\n";
2689
2690 frag
2691 << "#version 450\n"
2692 << "layout (location=0) out vec4 outColor;\n"
2693 << "void main() {\n"
2694 << " outColor = vec4(1.0f);\n"
2695 << "}\n";
2696 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
2697 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
2698 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
2699 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
2700 }
2701
2702 }
2703
2704 tcu::TestCaseGroup* createShaderObjectMiscTests(tcu::TestContext& testCtx)
2705 {
2706 de::MovePtr<tcu::TestCaseGroup> miscGroup(new tcu::TestCaseGroup(testCtx, "misc"));
2707
2708 const struct
2709 {
2710 deUint32 stride;
2711 const char* name;
2712 } strideTests[] =
2713 {
2714 { 16, "16", },
2715 { 32, "32", },
2716 { 48, "48", },
2717 { 40, "40", },
2718 };
2719
2720 for (deUint32 i = 0; i < 2; ++i)
2721 {
2722 bool blend1 = i == 0;
2723 de::MovePtr<tcu::TestCaseGroup> blend1Group(new tcu::TestCaseGroup(testCtx, blend1 ? "on" : "off"));
2724 for (deUint32 j = 0; j < 2; ++j)
2725 {
2726 bool blend2 = j == 0;
2727 de::MovePtr<tcu::TestCaseGroup> blend2Group(new tcu::TestCaseGroup(testCtx, blend2 ? "on" : "off"));
2728 for (deUint32 k = 0; k < 2; ++k)
2729 {
2730 bool vertexInputBefore = k == 0;
2731 de::MovePtr<tcu::TestCaseGroup> vertexInputBeforeGroup(new tcu::TestCaseGroup(testCtx, vertexInputBefore ? "before" : "after"));
2732 for (deUint32 l = 0; l < 2; ++l)
2733 {
2734 bool vertexBuffersNullStride = l == 0;
2735 de::MovePtr<tcu::TestCaseGroup> vertexBuffersNullStrideGroup(new tcu::TestCaseGroup(testCtx, vertexBuffersNullStride ? "null" : "non_null"));
2736 for (const auto& strideTest : strideTests)
2737 {
2738 de::MovePtr<tcu::TestCaseGroup> strideGroup(new tcu::TestCaseGroup(testCtx, strideTest.name));
2739 for (deUint32 m = 0; m < 2; ++m)
2740 {
2741 bool destroyDescriptorSetLayout = m == 1;
2742 std::string destroyName = destroyDescriptorSetLayout ? "set" : "destroyed";
2743
2744 TestParams params;
2745 params.blendEnabled[0] = blend1;
2746 params.blendEnabled[1] = blend2;
2747 params.vertexInputBefore = vertexInputBefore;
2748 params.vertexBuffersNullStride = vertexBuffersNullStride;
2749 params.stride = strideTest.stride;
2750 params.destroyDescriptorSetLayout = destroyDescriptorSetLayout;
2751 strideGroup->addChild(new ShaderObjectMiscCase(testCtx, destroyName, params));
2752 }
2753 vertexBuffersNullStrideGroup->addChild(strideGroup.release());
2754 }
2755 vertexInputBeforeGroup->addChild(vertexBuffersNullStrideGroup.release());
2756 }
2757 blend2Group->addChild(vertexInputBeforeGroup.release());
2758 }
2759 blend1Group->addChild(blend2Group.release());
2760 }
2761 miscGroup->addChild(blend1Group.release());
2762 }
2763
2764 const struct
2765 {
2766 bool pipeline;
2767 const char* name;
2768 } pipelineTests[] =
2769 {
2770 { false, "shaders" },
2771 { true, "pipeline" },
2772 };
2773
2774 const struct
2775 {
2776 bool meshShader;
2777 bool vertShader;
2778 bool tessShader;
2779 bool geomShader;
2780 bool fragShader;
2781 const char* name;
2782 } shadersTests[] =
2783 {
2784 { false, true, false, false, false, "vert", },
2785 { false, true, false, false, true, "vert_frag", },
2786 { false, true, true, false, true, "vert_tess_frag", },
2787 { false, true, false, true, true, "vert_geom_frag", },
2788 { false, true, true, true, true, "vert_tess_geom_frag", },
2789 { true, false, false, false, true, "mesh_frag", },
2790 };
2791
2792 const struct
2793 {
2794 bool alphaToOne;
2795 const char* name;
2796 } alphaToOneTests[] =
2797 {
2798 { false, "disabled" },
2799 { true, "enabled" },
2800 };
2801
2802 const struct
2803 {
2804 bool depthTestEnable;
2805 bool depthBounds;
2806 bool depthBoundsTestEnable;
2807 bool depthClamp;
2808 bool depthClip;
2809 bool depthClipControl;
2810 bool depthBiasEnable;
2811 const char* name;
2812 } depthTests[]
2813 {
2814 { false, false, false, false, false, false, false, "none" },
2815 { true, true, false, false, false, false, false, "bounds_disabled" },
2816 { true, true, true, false, false, false, false, "bounds_enabled" },
2817 { true, false, false, true, false, false, false, "clamp" },
2818 { true, false, false, false, true, false, false, "clip" },
2819 { true, false, false, false, false, true, false, "clip_control" },
2820 { true, false, false, false, false, false, true, "bias" },
2821 };
2822
2823 const struct
2824 {
2825 bool discardRectangles;
2826 bool discardRectanglesEnabled;
2827 const char* name;
2828 } discardRectanglesTests[] =
2829 {
2830 { false, false, "disabled" },
2831 { true, false, "enabled" },
2832 { true, true, "discard" },
2833 };
2834
2835 const struct
2836 {
2837 bool rasterizationDiscardEnable;
2838 const char* name;
2839 } rasterizationDiscardEnableTests[] =
2840 {
2841 { false, "disabled" },
2842 { true, "enabled" },
2843 };
2844
2845 const struct
2846 {
2847 bool colorBlendEnable;
2848 const char* name;
2849 } colorBlendTests[] =
2850 {
2851 { false, "disabled" },
2852 { true, "enabled" },
2853 };
2854
2855 const struct
2856 {
2857 bool lines;
2858 const char* name;
2859 } primitiveTests[] =
2860 {
2861 { false, "triangles" },
2862 { true, "lines" },
2863 };
2864
2865 const struct
2866 {
2867 bool stencilEnable;
2868 const char* name;
2869 } stencilTests[] =
2870 {
2871 { false, "disabled" },
2872 { true, "enabled" },
2873 };
2874
2875 const struct
2876 {
2877 bool logicOp;
2878 bool logicOpEnable;
2879 const char* name;
2880 } logicOpTests[] =
2881 {
2882 { false, false, "disabled" },
2883 { true, false, "enabled" },
2884 { true, true, "copy" },
2885 };
2886
2887 const struct
2888 {
2889 bool geometryStreams;
2890 const char* name;
2891 } geometryStreamsTests[] =
2892 {
2893 { false, "disabled" },
2894 { true, "enabled" },
2895 };
2896
2897 const struct
2898 {
2899 bool provokingVertex;
2900 const char* name;
2901 } provokingVertexTests[] =
2902 {
2903 { false, "disabled" },
2904 { true, "enabled" },
2905 };
2906
2907 const struct
2908 {
2909 bool sampleLocations;
2910 bool sampleLocationsEnable;
2911 const char* name;
2912 } sampleLocationsTests[] =
2913 {
2914 { false, false, "disabled" },
2915 { true, false, "enabled" },
2916 { true, true, "used" },
2917 };
2918
2919 const struct
2920 {
2921 bool lineRasterization;
2922 bool stippledLineEnable;
2923 const char* name;
2924 } linesTests[] =
2925 {
2926 { false, false, "default" },
2927 { true, false, "rectangular" },
2928 { true, true, "rectangular_stippled" },
2929 };
2930
2931 const struct
2932 {
2933 bool cull;
2934 const char* name;
2935 } cullTests[] =
2936 {
2937 { false, "none" },
2938 { true, "front_and_back" },
2939 };
2940
2941 const struct
2942 {
2943 bool conservativeRasterization;
2944 bool conservativeRasterizationOverestimate;
2945 const char* name;
2946 } conservativeRasterizationTests[] =
2947 {
2948 { false, false, "disabled" },
2949 { true, false, "enabled" },
2950 { true, true, "overestimate" },
2951 };
2952
2953 const struct
2954 {
2955 bool colorWrite;
2956 bool colorWriteEnable;
2957 const char* name;
2958 } colorWriteEnableTests[] =
2959 {
2960 { false, false, "disabled" },
2961 { true, false, "false" },
2962 { true, true, "true" },
2963 };
2964
2965 de::MovePtr<tcu::TestCaseGroup> stateGroup(new tcu::TestCaseGroup(testCtx, "state"));
2966 for (const auto& pipelineTest : pipelineTests)
2967 {
2968 de::MovePtr<tcu::TestCaseGroup> pipelineGroup(new tcu::TestCaseGroup(testCtx, pipelineTest.name));
2969 for (const auto shadersTest : shadersTests)
2970 {
2971 de::MovePtr<tcu::TestCaseGroup> shadersGroup(new tcu::TestCaseGroup(testCtx, shadersTest.name));
2972
2973 StateTestParams params;
2974 params.pipeline = pipelineTest.pipeline;
2975 params.meshShader = shadersTest.meshShader;
2976 params.vertShader = shadersTest.vertShader;
2977 params.tessShader = shadersTest.tessShader;
2978 params.geomShader = shadersTest.geomShader;
2979 params.fragShader = shadersTest.fragShader;
2980 params.reset();
2981
2982 de::MovePtr<tcu::TestCaseGroup> alphaToOneGroup(new tcu::TestCaseGroup(testCtx, "alphaToOne"));
2983 for (const auto& alphaToOneTest : alphaToOneTests)
2984 {
2985 params.alphaToOne = alphaToOneTest.alphaToOne;
2986 alphaToOneGroup->addChild(new ShaderObjectStateCase(testCtx, alphaToOneTest.name, params));
2987 }
2988 shadersGroup->addChild(alphaToOneGroup.release());
2989 params.reset();
2990
2991 de::MovePtr<tcu::TestCaseGroup> depthGroup(new tcu::TestCaseGroup(testCtx, "depth"));
2992 for (const auto& depthTest : depthTests)
2993 {
2994 params.depthTestEnable = depthTest.depthTestEnable;
2995 params.depthBounds = depthTest.depthBounds;
2996 params.depthBoundsTestEnable = depthTest.depthBoundsTestEnable;
2997 params.depthClamp = depthTest.depthClamp;
2998 params.depthClip = depthTest.depthClip;
2999 params.depthClipControl = depthTest.depthClipControl;
3000 params.depthBiasEnable = depthTest.depthBiasEnable;
3001 depthGroup->addChild(new ShaderObjectStateCase(testCtx, depthTest.name, params));
3002 }
3003 shadersGroup->addChild(depthGroup.release());
3004 params.reset();
3005
3006 de::MovePtr<tcu::TestCaseGroup> discardRectanglesGroup(new tcu::TestCaseGroup(testCtx, "discard_rectangles"));
3007 for (const auto& discardRectangles : discardRectanglesTests)
3008 {
3009 params.discardRectangles = discardRectangles.discardRectangles;
3010 params.discardRectanglesEnable = discardRectangles.discardRectanglesEnabled;
3011 discardRectanglesGroup->addChild(new ShaderObjectStateCase(testCtx, discardRectangles.name, params));
3012 }
3013 shadersGroup->addChild(discardRectanglesGroup.release());
3014 params.reset();
3015
3016 de::MovePtr<tcu::TestCaseGroup> rasterizationDiscardEnableGroup(new tcu::TestCaseGroup(testCtx, "rasterization_discard"));
3017 for (const auto& rasterizationDiscardTest : rasterizationDiscardEnableTests)
3018 {
3019 params.rasterizerDiscardEnable = rasterizationDiscardTest.rasterizationDiscardEnable;
3020 rasterizationDiscardEnableGroup->addChild(new ShaderObjectStateCase(testCtx, rasterizationDiscardTest.name, params));
3021 }
3022 shadersGroup->addChild(rasterizationDiscardEnableGroup.release());
3023 params.reset();
3024
3025 de::MovePtr<tcu::TestCaseGroup> colorBlendGroup(new tcu::TestCaseGroup(testCtx, "color_blend"));
3026 for (const auto& colorBlendTest : colorBlendTests)
3027 {
3028 params.colorBlendEnable = colorBlendTest.colorBlendEnable;
3029 colorBlendGroup->addChild(new ShaderObjectStateCase(testCtx, colorBlendTest.name, params));
3030 }
3031 shadersGroup->addChild(colorBlendGroup.release());
3032 params.reset();
3033
3034 de::MovePtr<tcu::TestCaseGroup> primitivesGroup(new tcu::TestCaseGroup(testCtx, "primitives"));
3035 for (const auto& primitivesTest : primitiveTests)
3036 {
3037 params.lines = primitivesTest.lines;
3038 primitivesGroup->addChild(new ShaderObjectStateCase(testCtx, primitivesTest.name, params));
3039 }
3040 shadersGroup->addChild(primitivesGroup.release());
3041 params.reset();
3042
3043 de::MovePtr<tcu::TestCaseGroup> stencilGroup(new tcu::TestCaseGroup(testCtx, "stencil"));
3044 for (const auto& stencilTest : stencilTests)
3045 {
3046 params.stencilTestEnable = stencilTest.stencilEnable;
3047 stencilGroup->addChild(new ShaderObjectStateCase(testCtx, stencilTest.name, params));
3048 }
3049 shadersGroup->addChild(stencilGroup.release());
3050 params.reset();
3051
3052 de::MovePtr<tcu::TestCaseGroup> logicOpGroup(new tcu::TestCaseGroup(testCtx, "logic_op"));
3053 for (const auto& logicOpTest : logicOpTests)
3054 {
3055 params.logicOp = logicOpTest.logicOp;
3056 params.logicOpEnable = logicOpTest.logicOpEnable;
3057 logicOpGroup->addChild(new ShaderObjectStateCase(testCtx, logicOpTest.name, params));
3058 }
3059 shadersGroup->addChild(logicOpGroup.release());
3060 params.reset();
3061
3062 if (shadersTest.geomShader)
3063 {
3064 de::MovePtr<tcu::TestCaseGroup> geometryStreamsGroup(new tcu::TestCaseGroup(testCtx, "geometry_streams"));
3065 for (const auto& geometryStreamsTest : geometryStreamsTests)
3066 {
3067 params.geometryStreams = geometryStreamsTest.geometryStreams;
3068 geometryStreamsGroup->addChild(new ShaderObjectStateCase(testCtx, geometryStreamsTest.name, params));
3069 }
3070 shadersGroup->addChild(geometryStreamsGroup.release());
3071 params.reset();
3072 }
3073
3074 de::MovePtr<tcu::TestCaseGroup> provokingVertexGroup(new tcu::TestCaseGroup(testCtx, "provoking_vertex"));
3075 for (const auto& provokingVertexTest : provokingVertexTests)
3076 {
3077 params.provokingVertex = provokingVertexTest.provokingVertex;
3078 provokingVertexGroup->addChild(new ShaderObjectStateCase(testCtx, provokingVertexTest.name, params));
3079 }
3080 shadersGroup->addChild(provokingVertexGroup.release());
3081 params.reset();
3082
3083 de::MovePtr<tcu::TestCaseGroup> sampleLocationsGroup(new tcu::TestCaseGroup(testCtx, "sample_locations"));
3084 for (const auto& sampleLocationsTest : sampleLocationsTests)
3085 {
3086 params.sampleLocations = sampleLocationsTest.sampleLocations;
3087 params.sampleLocationsEnable = sampleLocationsTest.sampleLocationsEnable;
3088 sampleLocationsGroup->addChild(new ShaderObjectStateCase(testCtx, sampleLocationsTest.name, params));
3089 }
3090 shadersGroup->addChild(sampleLocationsGroup.release());
3091 params.reset();
3092
3093 de::MovePtr<tcu::TestCaseGroup> linesGroup(new tcu::TestCaseGroup(testCtx, "lines"));
3094 for (const auto& linesTest : linesTests)
3095 {
3096 params.lines = true;
3097 params.stippledLineEnable = linesTest.stippledLineEnable;
3098 params.lineRasterization = linesTest.lineRasterization;
3099 linesGroup->addChild(new ShaderObjectStateCase(testCtx, linesTest.name, params));
3100 }
3101 shadersGroup->addChild(linesGroup.release());
3102 params.reset();
3103
3104 de::MovePtr<tcu::TestCaseGroup> cullGroup(new tcu::TestCaseGroup(testCtx, "cull"));
3105 for (const auto& cullTest : cullTests)
3106 {
3107 params.cull = cullTest.cull;
3108 cullGroup->addChild(new ShaderObjectStateCase(testCtx, cullTest.name, params));
3109 }
3110 shadersGroup->addChild(cullGroup.release());
3111 params.reset();
3112
3113 de::MovePtr<tcu::TestCaseGroup> conservativeRasterizationGroup(new tcu::TestCaseGroup(testCtx, "conservative_rasterization"));
3114 for (const auto& conservativeRasterizationTest : conservativeRasterizationTests)
3115 {
3116 params.conservativeRasterization = conservativeRasterizationTest.conservativeRasterization;
3117 params.conservativeRasterizationOverestimate = conservativeRasterizationTest.conservativeRasterizationOverestimate;
3118 conservativeRasterizationGroup->addChild(new ShaderObjectStateCase(testCtx, conservativeRasterizationTest.name, params));
3119 }
3120 shadersGroup->addChild(conservativeRasterizationGroup.release());
3121 params.reset();
3122
3123 de::MovePtr<tcu::TestCaseGroup> colorWriteGroup(new tcu::TestCaseGroup(testCtx, "color_write"));
3124 for (const auto& colorWriteEnableTest : colorWriteEnableTests)
3125 {
3126 params.colorWrite = colorWriteEnableTest.colorWrite;
3127 params.colorWriteEnable = colorWriteEnableTest.colorWriteEnable;
3128 colorWriteGroup->addChild(new ShaderObjectStateCase(testCtx, colorWriteEnableTest.name, params));
3129 }
3130 shadersGroup->addChild(colorWriteGroup.release());
3131 params.reset();
3132
3133 pipelineGroup->addChild(shadersGroup.release());
3134 }
3135 stateGroup->addChild(pipelineGroup.release());
3136 }
3137 miscGroup->addChild(stateGroup.release());
3138
3139 const struct
3140 {
3141 bool linked;
3142 const char* name;
3143 } linkedTests[] =
3144 {
3145 { false, "unlinked" },
3146 { true, "linked" },
3147 };
3148
3149 const struct
3150 {
3151 vk::VkShaderStageFlagBits stage;
3152 const char* name;
3153 } shaderStageTests[] =
3154 {
3155 { vk::VK_SHADER_STAGE_VERTEX_BIT, "vert" },
3156 { vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "tesc" },
3157 { vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "tese" },
3158 { vk::VK_SHADER_STAGE_GEOMETRY_BIT, "geom" },
3159 };
3160
3161 const struct
3162 {
3163 bool builtin;
3164 const char* name;
3165 } typeTests[] =
3166 {
3167 { false, "output" },
3168 { true, "builtin" },
3169 };
3170
3171 de::MovePtr<tcu::TestCaseGroup> unusedVariableGroup(new tcu::TestCaseGroup(testCtx, "unused_variable"));
3172 for (const auto& linkedTest : linkedTests)
3173 {
3174 de::MovePtr<tcu::TestCaseGroup> linkedGroup(new tcu::TestCaseGroup(testCtx, linkedTest.name));
3175 for (const auto& typeTest : typeTests)
3176 {
3177 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(testCtx, typeTest.name));
3178 for (const auto& shaderStageTest : shaderStageTests)
3179 {
3180 UnusedBuiltinParams params;
3181 params.linked = linkedTest.linked;
3182 params.stage = shaderStageTest.stage;
3183 params.builtin = typeTest.builtin;
3184 typeGroup->addChild(new ShaderObjectUnusedBuiltinCase(testCtx, shaderStageTest.name, params));
3185 }
3186 linkedGroup->addChild(typeGroup.release());
3187 }
3188 unusedVariableGroup->addChild(linkedGroup.release());
3189 }
3190 miscGroup->addChild(unusedVariableGroup.release());
3191
3192 const struct
3193 {
3194 deUint32 subdivision;
3195 const char* name;
3196 } subdivisionTests[] =
3197 {
3198 { 1, "one" },
3199 { 2, "two" },
3200 };
3201
3202 const struct
3203 {
3204 TessellationSpacing spacing;
3205 const char* name;
3206 } spacingTests[] =
3207 {
3208 { EQUAL, "equal" },
3209 { EVEN, "even" },
3210 { ODD, "odd" },
3211 };
3212
3213 de::MovePtr<tcu::TestCaseGroup> tessellationModesGroup(new tcu::TestCaseGroup(testCtx, "tessellation_modes"));
3214 for (const auto& subdivisionTest : subdivisionTests)
3215 {
3216 de::MovePtr<tcu::TestCaseGroup> subdivisionGroup(new tcu::TestCaseGroup(testCtx, subdivisionTest.name));
3217
3218 for (const auto& spacingTest : spacingTests)
3219 {
3220 TessellationModesParams params;
3221 params.subdivision = subdivisionTest.subdivision;
3222 params.spacing = spacingTest.spacing;
3223 subdivisionGroup->addChild(new ShaderObjectTessellationModesCase(testCtx, spacingTest.name, params));
3224 }
3225 tessellationModesGroup->addChild(subdivisionGroup.release());
3226 }
3227 miscGroup->addChild(tessellationModesGroup.release());
3228
3229 return miscGroup.release();
3230 }
3231
3232 } // ShaderObject
3233 } // vkt
3234