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