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 Binding Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktShaderObjectBindingTests.hpp"
26 #include "deUniquePtr.hpp"
27 #include "tcuTestCase.hpp"
28 #include "vktTestCase.hpp"
29 #include "vkShaderObjectUtil.hpp"
30 #include "vktShaderObjectCreateUtil.hpp"
31 #include "vkCmdUtil.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkImageWithMemory.hpp"
35 #include "vkBufferWithMemory.hpp"
36 #include "vkObjUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "vkBarrierUtil.hpp"
39 #include "deMath.h"
40 #include "vktCustomInstancesDevices.hpp"
41 #include "tcuCommandLine.hpp"
42 #include "vkBuilderUtil.hpp"
43
44 namespace vkt
45 {
46 namespace ShaderObject
47 {
48
49 namespace
50 {
51
52 enum TestType {
53 PASSTHROUGH_GEOM,
54 SWAP,
55 DISABLED,
56 UNBIND,
57 DRAW_DISPATCH_DRAW,
58 DISPATCH_DRAW_DISPATCH,
59 };
60
61 struct BindingDrawParams {
62 TestType testType;
63 vk::VkShaderStageFlagBits stage;
64 vk::VkShaderStageFlagBits unusedOutputs;
65 vk::VkShaderStageFlagBits binaryStage;
66 bool bindUnsupported;
67 bool setStateAfter;
68 bool unbindWithNullpShaders;
69 };
70
71 struct MeshBindingDrawParams {
72 vk::VkShaderStageFlagBits stage;
73 };
74
75 struct BindingParams {
76 bool useMeshShaders;
77 };
78
79 class ShaderObjectBindingDrawInstance : public vkt::TestInstance
80 {
81 public:
ShaderObjectBindingDrawInstance(Context & context,const BindingDrawParams & params)82 ShaderObjectBindingDrawInstance (Context& context, const BindingDrawParams& params)
83 : vkt::TestInstance (context)
84 , m_params (params)
85 {}
~ShaderObjectBindingDrawInstance(void)86 virtual ~ShaderObjectBindingDrawInstance (void) {}
87
88 tcu::TestStatus iterate (void) override;
89 private:
90 vk::Move<vk::VkShaderEXT> createShader (const vk::DeviceInterface& vk, const vk::VkDevice device, vk::VkShaderStageFlagBits stage, const std::string& name, const vk::VkDescriptorSetLayout* descriptorSetLayout = DE_NULL);
91 void createDevice (void);
getDevice(void)92 vk::VkDevice getDevice (void) { return (m_params.testType == DISABLED) ? m_customDevice.get() : m_context.getDevice(); }
93 void setDynamicStates (vk::VkCommandBuffer cmdBuffer, bool tessShader);
94
95 BindingDrawParams m_params;
96 vk::Move<vk::VkDevice> m_customDevice;
97 };
98
createDevice(void)99 void ShaderObjectBindingDrawInstance::createDevice (void)
100 {
101 if (m_params.testType != DISABLED)
102 return;
103
104 const float queuePriority = 1.0f;
105 const auto& deviceExtensions = m_context.getDeviceCreationExtensions();
106 auto features2 = m_context.getDeviceFeatures2();
107
108 if (m_params.stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
109 features2.features.geometryShader = VK_FALSE;
110 else if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
111 features2.features.tessellationShader = VK_FALSE;
112
113 vk::VkDeviceQueueCreateInfo queueInfo =
114 {
115 vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
116 DE_NULL, // const void* pNext;
117 0u, // VkDeviceQueueCreateFlags flags;
118 0u, // deUint32 queueFamilyIndex;
119 1u, // deUint32 queueCount;
120 &queuePriority // const float* pQueuePriorities;
121 };
122
123 const vk::VkDeviceCreateInfo deviceInfo =
124 {
125 vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType;
126 &features2, // const void* pNext;
127 (vk::VkDeviceCreateFlags)0, // VkDeviceCreateFlags flags;
128 1u, // uint32_t queueCreateInfoCount;
129 &queueInfo, // const VkDeviceQueueCreateInfo* pQueueCreateInfos;
130 0u, // uint32_t enabledLayerCount;
131 DE_NULL, // const char* const* ppEnabledLayerNames;
132 deUint32(deviceExtensions.size()), // uint32_t enabledExtensionCount;
133 (deviceExtensions.empty()) ? DE_NULL : deviceExtensions.data(), // const char* const* ppEnabledExtensionNames;
134 DE_NULL // const VkPhysicalDeviceFeatures* pEnabledFeatures;
135 };
136
137 m_customDevice = createCustomDevice(m_context.getTestContext().getCommandLine().isValidationEnabled(), m_context.getPlatformInterface(), m_context.getInstance(), m_context.getInstanceInterface(), m_context.getPhysicalDevice(), &deviceInfo);
138 }
139
createShader(const vk::DeviceInterface & vk,const vk::VkDevice device,vk::VkShaderStageFlagBits stage,const std::string & name,const vk::VkDescriptorSetLayout * descriptorSetLayout)140 vk::Move<vk::VkShaderEXT> ShaderObjectBindingDrawInstance::createShader (const vk::DeviceInterface& vk, const vk::VkDevice device, vk::VkShaderStageFlagBits stage, const std::string& name, const vk::VkDescriptorSetLayout* descriptorSetLayout)
141 {
142 const auto& binaries = m_context.getBinaryCollection();
143 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
144 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
145
146 if (m_params.binaryStage == stage)
147 {
148 auto shaderCreateInfo = vk::makeShaderCreateInfo(stage, binaries.get(name), tessellationSupported, geometrySupported, descriptorSetLayout);
149 const auto shader = vk::createShader(vk, device, shaderCreateInfo);
150
151 size_t dataSize;
152 vk.getShaderBinaryDataEXT(device, *shader, &dataSize, DE_NULL);
153 std::vector<deUint8> data(dataSize);
154 vk.getShaderBinaryDataEXT(device, *shader, &dataSize, data.data());
155
156 shaderCreateInfo.codeType = vk::VK_SHADER_CODE_TYPE_BINARY_EXT;
157 shaderCreateInfo.codeSize = dataSize;
158 shaderCreateInfo.pCode = data.data();
159
160 return vk::createShader(vk, device, shaderCreateInfo);
161 }
162
163 return vk::createShader(vk, device, vk::makeShaderCreateInfo(stage, binaries.get(name), tessellationSupported, geometrySupported, descriptorSetLayout));
164 }
165
setDynamicStates(vk::VkCommandBuffer cmdBuffer,bool tessShader)166 void ShaderObjectBindingDrawInstance::setDynamicStates (vk::VkCommandBuffer cmdBuffer, bool tessShader)
167 {
168 const vk::DeviceInterface& vk = m_context.getDeviceInterface();
169 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
170
171 const vk::VkPrimitiveTopology topology = tessShader ? vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
172
173 vk::setDefaultShaderObjectDynamicStates(vk, cmdBuffer, deviceExtensions, topology, false);
174
175 vk::VkBool32 colorBlendEnable = VK_TRUE;
176 vk.cmdSetColorBlendEnableEXT(cmdBuffer, 0u, 1u, &colorBlendEnable);
177 vk::VkColorBlendEquationEXT colorBlendEquation = {
178 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
179 vk::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,// VkBlendFactor dstColorBlendFactor;
180 vk::VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
181 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
182 vk::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,// VkBlendFactor dstAlphaBlendFactor;
183 vk::VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
184 };
185 vk.cmdSetColorBlendEquationEXT(cmdBuffer, 0u, 1u, &colorBlendEquation);
186 }
187
iterate(void)188 tcu::TestStatus ShaderObjectBindingDrawInstance::iterate (void)
189 {
190 const vk::VkInstance instance = m_context.getInstance();
191 const vk::InstanceDriver instanceDriver (m_context.getPlatformInterface(), instance);
192 createDevice();
193 const vk::DeviceInterface& vk = m_context.getDeviceInterface();
194 const vk::VkDevice device = getDevice();
195 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
196 const vk::VkQueue queue = getDeviceQueue(m_context.getDeviceInterface(), device, queueFamilyIndex, 0u);
197 auto alloctor = de::MovePtr<vk::Allocator>(new vk::SimpleAllocator(vk, device, getPhysicalDeviceMemoryProperties(instanceDriver, m_context.getPhysicalDevice())));
198 auto& alloc = *alloctor;
199 tcu::TestLog& log = m_context.getTestContext().getLog();
200
201 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
202 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
203 const bool taskSupported = m_context.getMeshShaderFeatures().taskShader;
204 const bool meshSupported = m_context.getMeshShaderFeatures().meshShader;
205
206 vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
207 const auto subresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
208 const auto subresourceLayers = vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
209 const vk::VkRect2D renderArea = vk::makeRect2D(0, 0, 32, 32);
210 vk::VkExtent3D extent = { renderArea.extent.width, renderArea.extent.height, 1};
211
212 const vk::VkImageCreateInfo createInfo =
213 {
214 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
215 DE_NULL, // const void* pNext
216 0u, // VkImageCreateFlags flags
217 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
218 colorAttachmentFormat, // VkFormat format
219 { 32, 32, 1 }, // VkExtent3D extent
220 1u, // uint32_t mipLevels
221 1u, // uint32_t arrayLayers
222 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
223 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
224 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
225 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
226 0, // uint32_t queueFamilyIndexCount
227 DE_NULL, // const uint32_t* pQueueFamilyIndices
228 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
229 };
230
231 de::MovePtr<vk::ImageWithMemory> image = de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
232 const auto imageView = vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
233
234 const vk::VkDeviceSize colorOutputBufferSize = renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
235 de::MovePtr<vk::BufferWithMemory> colorOutputBuffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
236 vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT), vk::MemoryRequirement::HostVisible));
237
238 const vk::VkDeviceSize bufferSizeBytes = sizeof(deUint32) * 16;
239 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
240 vk::DescriptorSetLayoutBuilder()
241 .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
242 .build(vk, device));
243
244 const vk::Unique<vk::VkDescriptorPool> descriptorPool(
245 vk::DescriptorPoolBuilder()
246 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2u)
247 .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 2u));
248
249 const vk::Move<vk::VkCommandPool> cmdPool (vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
250 const vk::Move<vk::VkCommandBuffer> cmdBuffer (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
251
252 const vk::Unique<vk::VkDescriptorSet> descriptorSet1 (vk::makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
253 const vk::Unique<vk::VkDescriptorSet> descriptorSet2 (vk::makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
254 const vk::BufferWithMemory outputBuffer1 (vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), vk::MemoryRequirement::HostVisible);
255 const vk::BufferWithMemory outputBuffer2 (vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), vk::MemoryRequirement::HostVisible);
256
257 const auto computePipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout.get());
258
259 const vk::VkDescriptorBufferInfo descriptorInfo1 = vk::makeDescriptorBufferInfo(*outputBuffer1, 0ull, bufferSizeBytes);
260 const vk::VkDescriptorBufferInfo descriptorInfo2 = vk::makeDescriptorBufferInfo(*outputBuffer2, 0ull, bufferSizeBytes);
261 vk::DescriptorSetUpdateBuilder()
262 .writeSingle(*descriptorSet1, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo1)
263 .update(vk, device);
264 vk::DescriptorSetUpdateBuilder()
265 .writeSingle(*descriptorSet2, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo2)
266 .update(vk, device);
267
268 vk::Move<vk::VkShaderEXT> vertShader;
269 vk::Move<vk::VkShaderEXT> tescShader;
270 vk::Move<vk::VkShaderEXT> teseShader;
271 vk::Move<vk::VkShaderEXT> geomShader;
272 vk::Move<vk::VkShaderEXT> fragShader;
273 vk::Move<vk::VkShaderEXT> compShader;
274 vk::Move<vk::VkShaderEXT> passThroughGeomShader;
275 vk::Move<vk::VkShaderEXT> vertAltShader;
276 vk::Move<vk::VkShaderEXT> tescAltShader;
277 vk::Move<vk::VkShaderEXT> teseAltShader;
278 vk::Move<vk::VkShaderEXT> geomAltShader;
279 vk::Move<vk::VkShaderEXT> fragAltShader;
280
281 if (tessellationSupported && geometrySupported)
282 {
283 vertShader = createShader(vk, device, vk::VK_SHADER_STAGE_VERTEX_BIT, "vert");
284 vertAltShader = createShader(vk, device, vk::VK_SHADER_STAGE_VERTEX_BIT, "vertAlt");
285 }
286 else if (tessellationSupported)
287 {
288 vertShader = createShader(vk, device, vk::VK_SHADER_STAGE_VERTEX_BIT, "vertNoGeom");
289 vertAltShader = createShader(vk, device, vk::VK_SHADER_STAGE_VERTEX_BIT, "vertAltNoGeom");
290 }
291 else if (geometrySupported)
292 {
293 vertShader = createShader(vk, device, vk::VK_SHADER_STAGE_VERTEX_BIT, "vertNoTess");
294 vertAltShader = createShader(vk, device, vk::VK_SHADER_STAGE_VERTEX_BIT, "vertAltNoTess");
295 }
296 else
297 {
298 vertShader = createShader(vk, device, vk::VK_SHADER_STAGE_VERTEX_BIT, "vertNoTessGeom");
299 vertAltShader = createShader(vk, device, vk::VK_SHADER_STAGE_VERTEX_BIT, "vertAltNoTessGeom");
300 }
301 if (tessellationSupported && (m_params.stage != vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || m_params.testType != DISABLED))
302 {
303 tescShader = createShader(vk, device, vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "tesc");
304 teseShader = createShader(vk, device, vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "tese");
305 tescAltShader = createShader(vk, device, vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "tescAlt");
306 teseAltShader = createShader(vk, device, vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "teseAlt");
307 }
308 if (geometrySupported && (m_params.stage != vk::VK_SHADER_STAGE_GEOMETRY_BIT || m_params.testType != DISABLED))
309 {
310 geomShader = createShader(vk, device, vk::VK_SHADER_STAGE_GEOMETRY_BIT, "geom");
311 geomAltShader = createShader(vk, device, vk::VK_SHADER_STAGE_GEOMETRY_BIT, "geomAlt");
312 passThroughGeomShader = createShader(vk, device, vk::VK_SHADER_STAGE_GEOMETRY_BIT, "passThroughGeom");
313 }
314 fragShader = createShader(vk, device, vk::VK_SHADER_STAGE_FRAGMENT_BIT, "blendFrag");
315 compShader = createShader(vk, device, vk::VK_SHADER_STAGE_COMPUTE_BIT, "comp", &*descriptorSetLayout);
316 fragAltShader = createShader(vk, device, vk::VK_SHADER_STAGE_FRAGMENT_BIT, "fragAlt");
317
318 const vk::VkClearValue clearValue = vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 0.0f });
319 vk::beginCommandBuffer(vk, *cmdBuffer);
320
321 vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
322 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &preImageBarrier);
323
324 if (!m_params.setStateAfter)
325 setDynamicStates(*cmdBuffer, tessellationSupported);
326
327 vk::VkBool32 colorBlendEnable = VK_TRUE;
328 vk.cmdSetColorBlendEnableEXT(*cmdBuffer, 0u, 1u, &colorBlendEnable);
329 vk::VkColorBlendEquationEXT colorBlendEquation = {
330 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
331 vk::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,// VkBlendFactor dstColorBlendFactor;
332 vk::VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
333 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
334 vk::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,// VkBlendFactor dstAlphaBlendFactor;
335 vk::VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
336 };
337 vk.cmdSetColorBlendEquationEXT(*cmdBuffer, 0u, 1u, &colorBlendEquation);
338
339 if (m_params.testType != DISPATCH_DRAW_DISPATCH)
340 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
341
342 vk::VkShaderEXT nullShader = VK_NULL_HANDLE;
343
344 if (m_params.testType == PASSTHROUGH_GEOM)
345 {
346 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, *tescShader, *teseShader, *passThroughGeomShader, *fragShader, taskSupported, meshSupported);
347 if (m_params.setStateAfter)
348 setDynamicStates(*cmdBuffer, tessellationSupported);
349 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
350 vk::VkShaderStageFlagBits geomStage = vk::VK_SHADER_STAGE_GEOMETRY_BIT;
351 vk.cmdBindShadersEXT(*cmdBuffer, 1u, &geomStage, &nullShader);
352 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
353 }
354 else if (m_params.testType == SWAP)
355 {
356 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, *tescShader, *teseShader, *geomShader, *fragShader, taskSupported, meshSupported);
357 if (m_params.setStateAfter)
358 setDynamicStates(*cmdBuffer, tessellationSupported);
359 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
360 vk::VkShaderEXT shader = VK_NULL_HANDLE;
361 if (m_params.stage == vk::VK_SHADER_STAGE_VERTEX_BIT)
362 shader = *vertAltShader;
363 else if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
364 shader = *tescAltShader;
365 else if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
366 shader = *teseAltShader;
367 else if (m_params.stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
368 shader = *geomAltShader;
369 else if (m_params.stage == vk::VK_SHADER_STAGE_FRAGMENT_BIT)
370 shader = *fragAltShader;
371 vk.cmdBindShadersEXT(*cmdBuffer, 1u, &m_params.stage, &shader);
372 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
373 }
374 else if (m_params.testType == DISABLED)
375 {
376 if (taskSupported) {
377 vk::VkShaderStageFlagBits stage = vk::VK_SHADER_STAGE_TASK_BIT_EXT;
378 vk::VkShaderEXT shader = VK_NULL_HANDLE;
379 vk.cmdBindShadersEXT(*cmdBuffer, 1u, &stage, &shader);
380 }
381 if (meshSupported) {
382 vk::VkShaderStageFlagBits stage = vk::VK_SHADER_STAGE_MESH_BIT_EXT;
383 vk::VkShaderEXT shader = VK_NULL_HANDLE;
384 vk.cmdBindShadersEXT(*cmdBuffer, 1u, &stage, &shader);
385 }
386 if (m_params.stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
387 {
388 vk::VkShaderStageFlagBits stages[] = { vk::VK_SHADER_STAGE_VERTEX_BIT, vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, vk::VK_SHADER_STAGE_FRAGMENT_BIT };
389 vk::VkShaderEXT shaders[] = { *vertShader, *tescShader, *teseShader, *fragShader };
390 vk.cmdBindShadersEXT(*cmdBuffer, 4u, stages, shaders);
391 if (m_params.bindUnsupported)
392 vk.cmdBindShadersEXT(*cmdBuffer, 1u, &m_params.stage, &nullShader);
393 if (m_params.setStateAfter)
394 setDynamicStates(*cmdBuffer, tessellationSupported);
395 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
396 }
397 else
398 {
399 vk.cmdSetPrimitiveTopology(*cmdBuffer, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
400 vk::VkShaderStageFlagBits stages[] = { vk::VK_SHADER_STAGE_VERTEX_BIT, vk::VK_SHADER_STAGE_GEOMETRY_BIT, vk::VK_SHADER_STAGE_FRAGMENT_BIT };
401 vk::VkShaderEXT shaders[] = { *vertShader, *geomShader, *fragShader };
402 vk.cmdBindShadersEXT(*cmdBuffer, 3u, stages, shaders);
403 if (m_params.bindUnsupported)
404 vk.cmdBindShadersEXT(*cmdBuffer, 1u, &m_params.stage, &nullShader);
405 if (m_params.setStateAfter)
406 setDynamicStates(*cmdBuffer, tessellationSupported);
407 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
408 }
409 }
410 else if (m_params.testType == UNBIND)
411 {
412 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, *tescShader, *teseShader, *geomShader, *fragShader, taskSupported, meshSupported);
413 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
414 if (m_params.stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
415 {
416 if (m_params.unbindWithNullpShaders)
417 vk.cmdBindShadersEXT(*cmdBuffer, 1u, &m_params.stage, DE_NULL);
418 else
419 vk.cmdBindShadersEXT(*cmdBuffer, 1u, &m_params.stage, &nullShader);
420 }
421 else
422 {
423 vk::VkShaderStageFlagBits stages[] = { vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT };
424 vk::VkShaderEXT nullShaders[] = { VK_NULL_HANDLE, VK_NULL_HANDLE };
425 vk.cmdSetPrimitiveTopology(*cmdBuffer, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
426 if (m_params.unbindWithNullpShaders)
427 vk.cmdBindShadersEXT(*cmdBuffer, 2u, stages, DE_NULL);
428 else
429 vk.cmdBindShadersEXT(*cmdBuffer, 2u, stages, nullShaders);
430 }
431 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
432 }
433 else if (m_params.testType == DRAW_DISPATCH_DRAW)
434 {
435 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, *tescShader, *teseShader, *geomShader, *fragShader, taskSupported, meshSupported);
436 if (m_params.setStateAfter)
437 setDynamicStates(*cmdBuffer, tessellationSupported);
438 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
439 vk::VkShaderStageFlagBits computeStage = vk::VK_SHADER_STAGE_COMPUTE_BIT;
440 vk.cmdBindShadersEXT(*cmdBuffer, 1u, &computeStage, &*compShader);
441 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
442 }
443 else if (m_params.testType == DISPATCH_DRAW_DISPATCH)
444 {
445 vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, computePipelineLayout.get(), 0, 1, &descriptorSet1.get(), 0, DE_NULL);
446 vk::VkShaderStageFlagBits computeStage = vk::VK_SHADER_STAGE_COMPUTE_BIT;
447 vk.cmdBindShadersEXT(*cmdBuffer, 1u, &computeStage, &*compShader);
448 vk.cmdDispatch(*cmdBuffer, 1u, 1u, 1u);
449 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, *tescShader, *teseShader, *geomShader, *fragShader, taskSupported, meshSupported);
450 vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, computePipelineLayout.get(), 0, 1, &descriptorSet2.get(), 0, DE_NULL);
451 vk.cmdDispatch(*cmdBuffer, 1u, 1u, 1u);
452 }
453
454 if (m_params.testType != DISPATCH_DRAW_DISPATCH)
455 vk::endRendering(vk, *cmdBuffer);
456
457 vk::VkImageMemoryBarrier postImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
458 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarrier);
459
460 const vk::VkBufferImageCopy copyRegion = vk::makeBufferImageCopy(extent, subresourceLayers);
461 vk.cmdCopyImageToBuffer(*cmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u, ©Region);
462
463 vk::endCommandBuffer(vk, *cmdBuffer);
464
465 vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
466
467 tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(vk::mapVkFormat(colorAttachmentFormat), renderArea.extent.width, renderArea.extent.height, 1, (const void*)colorOutputBuffer->getAllocation().getHostPtr());
468
469 const deInt32 width = resultBuffer.getWidth();
470 const deInt32 height = resultBuffer.getHeight();
471 const float threshold = 1.0f / 256.0f;
472 deInt32 xOffset1 = width / 8;
473 deInt32 yOffset1 = height / 8;
474 deInt32 xOffset2 = width / 8;
475 deInt32 yOffset2 = height / 8;
476 tcu::Vec4 expectedColor1 = tcu::Vec4(0.75f, 0.75f, 0.75f, 0.75f);
477 tcu::Vec4 expectedColor2 = tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f);
478 tcu::Vec4 blackColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
479
480 if (m_params.testType == PASSTHROUGH_GEOM)
481 {
482 yOffset1 = height / 4;
483 xOffset2 = xOffset1;
484 yOffset2 = yOffset1;
485 }
486 else if (m_params.testType == SWAP)
487 {
488 if (m_params.stage == vk::VK_SHADER_STAGE_VERTEX_BIT)
489 {
490 xOffset2 = 0;
491 yOffset2 = 0;
492 }
493 else if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
494 {
495 xOffset2 = 10;
496 yOffset2 = 10;
497 }
498 else if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
499 {
500 xOffset2 = 12;
501 yOffset2 = height / 8;
502 }
503 else if (m_params.stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
504 {
505 xOffset2 = width / 8;
506 yOffset2 = 12;
507 }
508 else if (m_params.stage == vk::VK_SHADER_STAGE_FRAGMENT_BIT)
509 {
510 expectedColor1 = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
511 }
512 }
513 else if (m_params.testType == DISABLED)
514 {
515 if (m_params.stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
516 {
517 yOffset1 = height / 4;
518 xOffset2 = 16;
519 yOffset2 = 16;
520 }
521 else
522 {
523 xOffset1 = width / 4;
524 xOffset2 = 16;
525 yOffset2 = 16;
526 }
527 }
528 else if (m_params.testType == UNBIND)
529 {
530 if (m_params.stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
531 {
532 xOffset2 = xOffset1;
533 yOffset2 = yOffset1 * 2;
534 }
535 else
536 {
537 xOffset2 = xOffset1 * 2;
538 yOffset2 = yOffset1;
539 }
540 }
541 else if (m_params.testType == DRAW_DISPATCH_DRAW)
542 {
543 xOffset2 = xOffset1;
544 yOffset2 = yOffset1;
545 }
546
547 if (m_params.testType == DISPATCH_DRAW_DISPATCH)
548 {
549 for (deUint32 i = 0; i < 2; ++i)
550 {
551 const vk::Allocation& outputBufferAllocation = i == 0 ? outputBuffer1.getAllocation() : outputBuffer2.getAllocation();
552 invalidateAlloc(vk, device, outputBufferAllocation);
553
554 const deUint32* bufferPtr = static_cast<deUint32*>(outputBufferAllocation.getHostPtr());
555
556 for (deUint32 j = 0; j < 16; ++j)
557 {
558 if (bufferPtr[j] != j)
559 return tcu::TestStatus::fail("Fail");
560 }
561 }
562 return tcu::TestStatus::pass("Pass");
563 }
564
565 for (deInt32 j = 0; j < height; ++j)
566 {
567 for (deInt32 i = 0; i < width; ++i)
568 {
569 const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
570
571 bool first = i >= xOffset1 && i < width - xOffset1 && j >= yOffset1 && j < height - yOffset1;
572 bool second = i >= xOffset2 && i < width - xOffset2 && j >= yOffset2 && j < height - yOffset2;
573 tcu::Vec4 expectedColor = blackColor;
574 if (first && second)
575 expectedColor = expectedColor1;
576 else if (first || second)
577 expectedColor = expectedColor2;
578
579 if (deFloatAbs(color.x() - expectedColor.x()) > threshold || deFloatAbs(color.y() - expectedColor.y()) > threshold || deFloatAbs(color.z() - expectedColor.z()) > threshold || deFloatAbs(color.w() - expectedColor.w()) > threshold)
580 {
581 log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") is expected to be (" << expectedColor << "), but was (" << color << ")" << tcu::TestLog::EndMessage;
582 return tcu::TestStatus::fail("Fail");
583 }
584 }
585 }
586
587 return tcu::TestStatus::pass("Pass");
588 }
589
590 class ShaderObjectBindingDrawCase : public vkt::TestCase
591 {
592 public:
ShaderObjectBindingDrawCase(tcu::TestContext & testCtx,const std::string & name,const BindingDrawParams & params)593 ShaderObjectBindingDrawCase (tcu::TestContext& testCtx, const std::string& name, const BindingDrawParams& params)
594 : vkt::TestCase (testCtx, name)
595 , m_params (params)
596 {}
~ShaderObjectBindingDrawCase(void)597 virtual ~ShaderObjectBindingDrawCase (void) {}
598
599 void checkSupport (vkt::Context& context) const override;
600 virtual void initPrograms (vk::SourceCollections& programCollection) const override;
createInstance(Context & context) const601 TestInstance* createInstance (Context& context) const override { return new ShaderObjectBindingDrawInstance(context, m_params); }
602 private:
603 BindingDrawParams m_params;
604 };
605
checkSupport(Context & context) const606 void ShaderObjectBindingDrawCase::checkSupport (Context& context) const
607 {
608 context.requireDeviceFunctionality("VK_EXT_shader_object");
609
610 if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT ||
611 m_params.binaryStage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || m_params.binaryStage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
612 context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
613
614 if (m_params.stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT || m_params.binaryStage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
615 context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
616 }
617
initPrograms(vk::SourceCollections & programCollection) const618 void ShaderObjectBindingDrawCase::initPrograms(vk::SourceCollections& programCollection) const
619 {
620 vk::addBasicShaderObjectShaders(programCollection);
621
622 std::stringstream passThroughGeom;
623 std::stringstream blendFrag;
624 std::stringstream vertAlt;
625 std::stringstream geomAlt;
626 std::stringstream tescAlt;
627 std::stringstream teseAlt;
628 std::stringstream fragAlt;
629 std::stringstream vertNoTess;
630 std::stringstream vertNoGeom;
631 std::stringstream vertNoTessGeom;
632 std::stringstream vertAltNoTess;
633 std::stringstream vertAltNoGeom;
634 std::stringstream vertAltNoTessGeom;
635
636 vertNoTess
637 << "#version 450\n"
638 << "void main() {\n"
639 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
640 << " gl_Position = vec4((pos.x - 0.5f) * 1.5f, pos.y - 0.5f, 0.0f, 1.0f);\n"
641 << "}\n";
642
643 vertNoGeom
644 << "#version 450\n"
645 << "void main() {\n"
646 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
647 << " gl_Position = vec4(pos.x - 0.5f, (pos.y - 0.5f) * 1.5f, 0.0f, 1.0f);\n"
648 << "}\n";
649
650 vertNoTessGeom
651 << "#version 450\n"
652 << "void main() {\n"
653 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
654 << " gl_Position = vec4((pos - 0.5f) * 1.5f, 0.0f, 1.0f);\n"
655 << "}\n";
656
657 passThroughGeom
658 << "#version 450\n"
659 << "layout(triangles) in;\n"
660 << "layout(triangle_strip, max_vertices = 4) out;\n"
661 << "\n"
662 << "void main(void)\n"
663 << "{\n"
664 << " gl_Position = gl_in[0].gl_Position;\n"
665 << " EmitVertex();\n"
666 << " gl_Position = gl_in[1].gl_Position;\n"
667 << " EmitVertex();\n"
668 << " gl_Position = gl_in[2].gl_Position;\n"
669 << " EmitVertex();\n"
670 << " EndPrimitive();\n"
671 << "}\n";
672
673 blendFrag
674 << "#version 450\n"
675 << "layout (location=0) out vec4 outColor;\n"
676 << "void main() {\n"
677 << " outColor = vec4(0.5f, 0.5f, 0.5f, 0.5f);\n"
678 << "}\n";
679
680 vertAlt
681 << "#version 450\n";
682 if (m_params.unusedOutputs == vk::VK_SHADER_STAGE_VERTEX_BIT)
683 vertAlt
684 << "layout (location = 0) out vec4 color;\n";
685 vertAlt
686 << "void main() {\n"
687 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
688 << " gl_Position = vec4((pos - 0.5f) * 2, 0.0f, 1.0f);\n";
689 if (m_params.unusedOutputs == vk::VK_SHADER_STAGE_VERTEX_BIT)
690 vertAlt
691 << "color = vec4(1.0f);\n";
692 vertAlt
693 << "}\n";
694
695 vertAltNoTess
696 << "#version 450\n";
697 if (m_params.unusedOutputs == vk::VK_SHADER_STAGE_VERTEX_BIT)
698 vertAltNoTess
699 << "layout (location = 0) out vec4 color;\n";
700 vertAltNoTess
701 << "void main() {\n"
702 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
703 << " gl_Position = vec4((pos.x - 0.5f) * 2.0f * 1.5f, (pos.y - 0.5f) * 2.0f, 0.0f, 1.0f);\n";
704 if (m_params.unusedOutputs == vk::VK_SHADER_STAGE_VERTEX_BIT)
705 vertAltNoTess
706 << " color = vec4(1.0f);\n";
707 vertAltNoTess
708 << "}\n";
709
710 vertAltNoGeom
711 << "#version 450\n";
712 if (m_params.unusedOutputs == vk::VK_SHADER_STAGE_VERTEX_BIT)
713 vertAltNoGeom
714 << "layout (location = 0) out vec4 color;\n";
715 vertAltNoGeom
716 << "void main() {\n"
717 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
718 << " gl_Position = vec4((pos.x - 0.5f) * 2.0f, (pos.y - 0.5f) * 2.0f * 1.5f, 0.0f, 1.0f);\n";
719 if (m_params.unusedOutputs == vk::VK_SHADER_STAGE_VERTEX_BIT)
720 vertAltNoGeom
721 << " color = vec4(1.0f);\n";
722 vertAltNoGeom
723 << "}\n";
724
725 vertAltNoTessGeom
726 << "#version 450\n";
727 if (m_params.unusedOutputs == vk::VK_SHADER_STAGE_VERTEX_BIT)
728 vertAltNoTessGeom
729 << "layout (location = 0) out vec4 color;\n";
730 vertAltNoTessGeom
731 << "void main() {\n"
732 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
733 << " gl_Position = vec4((pos - 0.5f) * 2 * 1.5f, 0.0f, 1.0f);\n";
734 if (m_params.unusedOutputs == vk::VK_SHADER_STAGE_VERTEX_BIT)
735 vertAltNoTessGeom
736 << " color = vec4(1.0f);\n";
737 vertAltNoTessGeom
738 << "}\n";
739
740 tescAlt
741 << "#version 450\n"
742 << "\n"
743 << "layout(vertices = 4) out;\n";
744 if (m_params.unusedOutputs == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
745 tescAlt
746 << "layout (location = 0) out vec4 color[];\n";
747 tescAlt
748 << "\n"
749 << "void main (void)\n"
750 << "{\n"
751 << " if (gl_InvocationID == 0) {\n"
752 << " gl_TessLevelInner[0] = 1.0;\n"
753 << " gl_TessLevelInner[1] = 1.0;\n"
754 << " gl_TessLevelOuter[0] = 1.0;\n"
755 << " gl_TessLevelOuter[1] = 1.0;\n"
756 << " gl_TessLevelOuter[2] = 1.0;\n"
757 << " gl_TessLevelOuter[3] = 1.0;\n"
758 << " }\n"
759 << " vec4 pos = gl_in[gl_InvocationID].gl_Position;\n"
760 << " pos.xy *= 0.5f;\n"
761 << " gl_out[gl_InvocationID].gl_Position = pos;\n";
762 if (m_params.unusedOutputs == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
763 tescAlt
764 << " color[gl_InvocationID] = vec4(1.0f);\n";
765 tescAlt
766 << "}\n";
767
768 teseAlt
769 << "#version 450\n"
770 << "\n"
771 << "layout(quads, equal_spacing) in;\n";
772 if (m_params.unusedOutputs == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
773 teseAlt
774 << "layout (location = 0) out vec4 color;\n";
775 teseAlt
776 << "\n"
777 << "void main (void)\n"
778 << "{\n"
779 << " float u = gl_TessCoord.x;\n"
780 << " float v = gl_TessCoord.y;\n"
781 << " float omu = 1.0f - u;\n"
782 << " float omv = 1.0f - v;\n"
783 << " gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
784 << " gl_Position.x *= 0.5f;\n";
785 if (m_params.unusedOutputs == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
786 teseAlt
787 << " color = vec4(1.0f);\n";
788 teseAlt
789 << "}\n";
790
791 geomAlt
792 << "#version 450\n"
793 << "layout(triangles) in;\n"
794 << "layout(triangle_strip, max_vertices = 4) out;\n";
795 if (m_params.unusedOutputs == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
796 geomAlt
797 << "layout (location = 0) out vec4 color;\n";
798 geomAlt
799 << "\n"
800 << "void main(void)\n"
801 << "{\n"
802 << " gl_Position = gl_in[0].gl_Position;\n"
803 << " gl_Position.y *= 0.5f;\n"
804 << " EmitVertex();\n"
805 << " gl_Position = gl_in[1].gl_Position;\n"
806 << " gl_Position.y *= 0.5f;\n"
807 << " EmitVertex();\n"
808 << " gl_Position = gl_in[2].gl_Position;\n"
809 << " gl_Position.y *= 0.5f;\n"
810 << " EmitVertex();\n"
811 << " EndPrimitive();\n";
812 if (m_params.unusedOutputs == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
813 geomAlt
814 << " color = vec4(1.0f);\n";
815 geomAlt
816 << "}\n";
817
818 fragAlt
819 << "#version 450\n"
820 << "layout (location=0) out vec4 outColor;\n";
821 if (m_params.unusedOutputs == vk::VK_SHADER_STAGE_FRAGMENT_BIT)
822 fragAlt
823 << "layout (location = 1) out vec4 color;\n";
824 fragAlt
825 << "void main() {\n"
826 << " outColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n";
827 if (m_params.unusedOutputs == vk::VK_SHADER_STAGE_FRAGMENT_BIT)
828 fragAlt
829 << "color = vec4(1.0f);\n";
830 fragAlt
831 << "}\n";
832
833 programCollection.glslSources.add("passThroughGeom") << glu::GeometrySource(passThroughGeom.str());
834 programCollection.glslSources.add("blendFrag") << glu::FragmentSource(blendFrag.str());
835 programCollection.glslSources.add("vertAlt") << glu::VertexSource(vertAlt.str());
836 programCollection.glslSources.add("tescAlt") << glu::TessellationControlSource(tescAlt.str());
837 programCollection.glslSources.add("teseAlt") << glu::TessellationEvaluationSource(teseAlt.str());
838 programCollection.glslSources.add("geomAlt") << glu::GeometrySource(geomAlt.str());
839 programCollection.glslSources.add("fragAlt") << glu::FragmentSource(fragAlt.str());
840
841 programCollection.glslSources.add("vertNoTess") << glu::VertexSource(vertNoTess.str());
842 programCollection.glslSources.add("vertNoGeom") << glu::VertexSource(vertNoGeom.str());
843 programCollection.glslSources.add("vertNoTessGeom") << glu::VertexSource(vertNoTessGeom.str());
844 programCollection.glslSources.add("vertAltNoTess") << glu::VertexSource(vertAltNoTess.str());
845 programCollection.glslSources.add("vertAltNoGeom") << glu::VertexSource(vertAltNoGeom.str());
846 programCollection.glslSources.add("vertAltNoTessGeom") << glu::VertexSource(vertAltNoTessGeom.str());
847 }
848
849
850 class ShaderObjectBindingInstance : public vkt::TestInstance
851 {
852 public:
ShaderObjectBindingInstance(Context & context,const BindingParams & params)853 ShaderObjectBindingInstance (Context& context, const BindingParams& params)
854 : vkt::TestInstance (context)
855 , m_params (params)
856 {}
~ShaderObjectBindingInstance(void)857 virtual ~ShaderObjectBindingInstance (void) {}
858
859 tcu::TestStatus iterate (void) override;
860 private:
861 BindingParams m_params;
862 };
863
iterate(void)864 tcu::TestStatus ShaderObjectBindingInstance::iterate (void)
865 {
866 const vk::VkInstance instance = m_context.getInstance();
867 const vk::InstanceDriver instanceDriver (m_context.getPlatformInterface(), instance);
868 const vk::DeviceInterface& vk = m_context.getDeviceInterface();
869 const vk::VkDevice device = m_context.getDevice();
870 const vk::VkQueue queue = m_context.getUniversalQueue();
871 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
872
873 const auto meshShaderFeatures = m_context.getMeshShaderFeatures();
874 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
875 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
876 const auto& binaries = m_context.getBinaryCollection();
877
878 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
879 vk::DescriptorSetLayoutBuilder()
880 .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT | ((m_params.useMeshShaders && meshShaderFeatures.meshShader) ? vk::VkShaderStageFlags{ vk::VK_SHADER_STAGE_MESH_BIT_EXT } : vk::VkShaderStageFlags{ 0 }))
881 .build(vk, device));
882
883 vk::Move<vk::VkShaderEXT> vertShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("vert"), tessellationSupported, geometrySupported));
884 vk::Move<vk::VkShaderEXT> tescShader;
885 vk::Move<vk::VkShaderEXT> teseShader;
886 vk::Move<vk::VkShaderEXT> geomShader;
887 vk::Move<vk::VkShaderEXT> fragShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("frag"), tessellationSupported, geometrySupported));
888 vk::Move<vk::VkShaderEXT> compShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_COMPUTE_BIT, binaries.get("comp"), tessellationSupported, geometrySupported, &*descriptorSetLayout));
889 vk::Move<vk::VkShaderEXT> taskShader;
890 vk::Move<vk::VkShaderEXT> meshShader;
891 if (m_context.getDeviceFeatures().tessellationShader)
892 {
893 tescShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, binaries.get("tesc"), tessellationSupported, geometrySupported));
894 teseShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, binaries.get("tese"), tessellationSupported, geometrySupported));
895 }
896 if (m_context.getDeviceFeatures().geometryShader)
897 {
898 geomShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_GEOMETRY_BIT, binaries.get("geom"), tessellationSupported, geometrySupported));
899 }
900 if (m_params.useMeshShaders)
901 {
902 if (meshShaderFeatures.taskShader)
903 taskShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TASK_BIT_EXT, binaries.get("task"), tessellationSupported, geometrySupported));
904 if (meshShaderFeatures.meshShader)
905 meshShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_MESH_BIT_EXT, binaries.get("mesh"), tessellationSupported, geometrySupported, &*descriptorSetLayout));
906 }
907
908 const vk::Move<vk::VkCommandPool> cmdPool (vk::createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
909 const vk::Move<vk::VkCommandBuffer> cmdBuffer (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
910
911 const bool bind[] = { true, false };
912 for (const auto bindVert : bind)
913 {
914 for (const auto bindTesc : bind)
915 {
916 for (const auto bindTese : bind)
917 {
918 for (const auto bindGeom : bind)
919 {
920 for (const auto bindFrag : bind)
921 {
922 for (const auto bindComp : bind)
923 {
924 for (const auto bindTask : bind)
925 {
926 if (bindVert && bindTask)
927 continue;
928 for (const auto bindMesh : bind)
929 {
930 if (bindVert && bindMesh)
931 continue;
932 std::vector<vk::VkShaderStageFlagBits> stages = {
933 vk::VK_SHADER_STAGE_VERTEX_BIT,
934 vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
935 vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
936 vk::VK_SHADER_STAGE_GEOMETRY_BIT,
937 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
938 vk::VK_SHADER_STAGE_COMPUTE_BIT,
939 vk::VK_SHADER_STAGE_MESH_BIT_EXT,
940 vk::VK_SHADER_STAGE_TASK_BIT_EXT,
941 };
942 std::vector<vk::VkShaderEXT> shaders =
943 {
944 bindVert ? *vertShader : VK_NULL_HANDLE,
945 (bindTesc && m_context.getDeviceFeatures().tessellationShader) ? *tescShader : VK_NULL_HANDLE,
946 (bindTese && m_context.getDeviceFeatures().tessellationShader) ? *teseShader : VK_NULL_HANDLE,
947 (bindGeom && m_context.getDeviceFeatures().geometryShader) ? *geomShader : VK_NULL_HANDLE,
948 bindFrag ? *fragShader : VK_NULL_HANDLE,
949 bindComp ? *compShader : VK_NULL_HANDLE,
950 bindMesh ? *meshShader : VK_NULL_HANDLE,
951 bindTask ? *taskShader : VK_NULL_HANDLE,
952 };
953 deUint32 count = 6u;
954 if (meshShaderFeatures.meshShader)
955 ++count;
956 if (meshShaderFeatures.taskShader)
957 ++count;
958 vk::beginCommandBuffer(vk, *cmdBuffer);
959 vk.cmdBindShadersEXT(*cmdBuffer, count, stages.data(), shaders.data());
960 vk::endCommandBuffer(vk, *cmdBuffer);
961 vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
962 }
963 }
964 }
965 }
966 }
967 }
968 }
969 }
970
971 if (m_context.getDeviceFeatures().tessellationShader && m_context.getDeviceFeatures().geometryShader && meshShaderFeatures.taskShader && meshShaderFeatures.meshShader)
972 {
973 std::vector<vk::VkShaderStageFlagBits> stages = {
974 vk::VK_SHADER_STAGE_VERTEX_BIT,
975 vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
976 vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
977 vk::VK_SHADER_STAGE_GEOMETRY_BIT,
978 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
979 vk::VK_SHADER_STAGE_COMPUTE_BIT,
980 vk::VK_SHADER_STAGE_MESH_BIT_EXT,
981 vk::VK_SHADER_STAGE_TASK_BIT_EXT,
982 };
983 vk::beginCommandBuffer(vk, *cmdBuffer);
984 vk.cmdBindShadersEXT(*cmdBuffer, (deUint32)stages.size(), stages.data(), DE_NULL);
985 vk::endCommandBuffer(vk, *cmdBuffer);
986 vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
987 }
988
989 return tcu::TestStatus::pass("pass");
990 }
991
992 class MeshShaderObjectBindingInstance : public vkt::TestInstance
993 {
994 public:
MeshShaderObjectBindingInstance(Context & context,const MeshBindingDrawParams & params)995 MeshShaderObjectBindingInstance (Context& context, const MeshBindingDrawParams& params)
996 : vkt::TestInstance (context)
997 , m_params (params)
998 {}
~MeshShaderObjectBindingInstance(void)999 virtual ~MeshShaderObjectBindingInstance (void) {}
1000
1001 tcu::TestStatus iterate (void) override;
1002 private:
1003 MeshBindingDrawParams m_params;
1004 };
1005
iterate(void)1006 tcu::TestStatus MeshShaderObjectBindingInstance::iterate (void)
1007 {
1008 const vk::VkInstance instance = m_context.getInstance();
1009 const vk::InstanceDriver instanceDriver (m_context.getPlatformInterface(), instance);
1010 const vk::DeviceInterface& vk = m_context.getDeviceInterface();
1011 const vk::VkDevice device = m_context.getDevice();
1012 const vk::VkQueue queue = m_context.getUniversalQueue();
1013 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1014 auto& alloc = m_context.getDefaultAllocator();
1015 tcu::TestLog& log = m_context.getTestContext().getLog();
1016 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
1017
1018 vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
1019 const auto subresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1020
1021 const vk::VkImageCreateInfo createInfo =
1022 {
1023 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
1024 DE_NULL, // const void* pNext
1025 0u, // VkImageCreateFlags flags
1026 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
1027 colorAttachmentFormat, // VkFormat format
1028 { 32, 32, 1 }, // VkExtent3D extent
1029 1u, // uint32_t mipLevels
1030 1u, // uint32_t arrayLayers
1031 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
1032 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
1033 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
1034 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
1035 0, // uint32_t queueFamilyIndexCount
1036 DE_NULL, // const uint32_t* pQueueFamilyIndices
1037 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
1038 };
1039
1040 de::MovePtr<vk::ImageWithMemory> image = de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
1041 const auto imageView = vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
1042 const vk::VkRect2D renderArea = vk::makeRect2D(0, 0, 32, 32);
1043
1044 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
1045 vk::DescriptorSetLayoutBuilder()
1046 .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_TASK_BIT_EXT | vk::VK_SHADER_STAGE_MESH_BIT_EXT)
1047 .build(vk, device));
1048
1049 const vk::Unique<vk::VkDescriptorPool> descriptorPool(
1050 vk::DescriptorPoolBuilder()
1051 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
1052 .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
1053
1054 const vk::VkDeviceSize bufferSizeBytes = sizeof(deUint32) * 4;
1055 const vk::Unique<vk::VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
1056 const vk::BufferWithMemory outputBuffer (vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), vk::MemoryRequirement::HostVisible);
1057
1058 const vk::VkDescriptorBufferInfo descriptorInfo = vk::makeDescriptorBufferInfo(*outputBuffer, 0ull, bufferSizeBytes);
1059 vk::DescriptorSetUpdateBuilder()
1060 .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
1061 .update(vk, device);
1062
1063 const auto pipelineLayout = makePipelineLayout(vk, device, *descriptorSetLayout);
1064
1065 const auto& binaries = m_context.getBinaryCollection();
1066 const auto taskShader1 = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TASK_BIT_EXT, binaries.get("task1"), false, false, &*descriptorSetLayout));
1067 const auto taskShader2 = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TASK_BIT_EXT, binaries.get("task2"), false, false, &*descriptorSetLayout));
1068 const auto meshShader1 = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_MESH_BIT_EXT, binaries.get("mesh1"), false, false, &*descriptorSetLayout));
1069 const auto meshShader2 = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_MESH_BIT_EXT, binaries.get("mesh2"), false, false, &*descriptorSetLayout));
1070 const auto fragShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("frag"), false, false, &*descriptorSetLayout));
1071
1072 const vk::Move<vk::VkCommandPool> cmdPool (vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
1073 const vk::Move<vk::VkCommandBuffer> cmdBuffer (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1074
1075 const vk::VkClearValue clearValue = vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 1.0f });
1076
1077 vk::beginCommandBuffer(vk, *cmdBuffer);
1078
1079 vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
1080 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &preImageBarrier);
1081
1082 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
1083 vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, true);
1084 vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0, 1, &descriptorSet.get(), 0, DE_NULL);
1085
1086 std::vector<vk::VkShaderStageFlagBits> nullStages = {
1087 vk::VK_SHADER_STAGE_VERTEX_BIT,
1088 };
1089 if (m_context.getDeviceFeatures().tessellationShader) {
1090 nullStages.push_back(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
1091 nullStages.push_back(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
1092 }
1093 if (m_context.getDeviceFeatures().geometryShader) {
1094 nullStages.push_back(vk::VK_SHADER_STAGE_GEOMETRY_BIT);
1095 }
1096 for (const auto& stage : nullStages) {
1097 vk::VkShaderEXT shader = VK_NULL_HANDLE;
1098 vk.cmdBindShadersEXT(*cmdBuffer, 1u, &stage, &shader);
1099 }
1100
1101 const vk::VkShaderStageFlagBits stages[] = {
1102 vk::VK_SHADER_STAGE_TASK_BIT_EXT,
1103 vk::VK_SHADER_STAGE_MESH_BIT_EXT,
1104 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
1105 };
1106 vk::VkShaderEXT shaders[] = {
1107 *taskShader1,
1108 *meshShader1,
1109 *fragShader,
1110 };
1111 vk.cmdBindShadersEXT(*cmdBuffer, 3u, stages, shaders);
1112 vk.cmdDrawMeshTasksEXT(*cmdBuffer, 1, 1, 1);
1113 vk::endRendering(vk, *cmdBuffer);
1114
1115 vk::VkBufferMemoryBarrier shaderBufferBarrier = vk::makeBufferMemoryBarrier(vk::VK_ACCESS_SHADER_WRITE_BIT, vk::VK_ACCESS_SHADER_WRITE_BIT, *outputBuffer, 0u, bufferSizeBytes);
1116 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 1u, &shaderBufferBarrier, 0u, (const vk::VkImageMemoryBarrier*)DE_NULL);
1117
1118 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_LOAD);
1119 if (m_params.stage == vk::VK_SHADER_STAGE_TASK_BIT_EXT)
1120 vk.cmdBindShadersEXT(*cmdBuffer, 1u, &stages[0], &*taskShader2);
1121 else if (m_params.stage == vk::VK_SHADER_STAGE_MESH_BIT_EXT)
1122 vk.cmdBindShadersEXT(*cmdBuffer, 1u, &stages[1], &*meshShader2);
1123 vk.cmdDrawMeshTasksEXT(*cmdBuffer, 1, 1, 1);
1124
1125 vk::endRendering(vk, *cmdBuffer);
1126
1127 vk::VkImageMemoryBarrier postImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
1128 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarrier);
1129 vk::VkBufferMemoryBarrier bufferBarrier = vk::makeBufferMemoryBarrier(vk::VK_ACCESS_SHADER_WRITE_BIT, vk::VK_ACCESS_HOST_READ_BIT, *outputBuffer, 0u, bufferSizeBytes);
1130 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 1u, &bufferBarrier, 0u, (const vk::VkImageMemoryBarrier*)DE_NULL);
1131 vk::endCommandBuffer(vk, *cmdBuffer);
1132
1133 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
1134
1135 const vk::Allocation& outputBufferAllocation = outputBuffer.getAllocation();
1136 invalidateAlloc(vk, device, outputBufferAllocation);
1137
1138 const deUint32* bufferPtr = static_cast<deUint32*>(outputBufferAllocation.getHostPtr());
1139
1140 if (m_params.stage == vk::VK_SHADER_STAGE_TASK_BIT_EXT)
1141 {
1142 if (bufferPtr[0] != 4u || bufferPtr[1] != 5u || bufferPtr[2] != 2u || bufferPtr[3] != 3u)
1143 {
1144 log << tcu::TestLog::Message << "Buffer values were expected to be [4, 5, 2, 3], but were[" << bufferPtr[0] << ", " << bufferPtr[1] << ", " << bufferPtr[2] << ", " << bufferPtr[3] << ", " << "]" << tcu::TestLog::EndMessage;
1145 return tcu::TestStatus::fail("Fail");
1146 }
1147 }
1148 else if (m_params.stage == vk::VK_SHADER_STAGE_MESH_BIT_EXT)
1149 {
1150 if (bufferPtr[0] != 0u || bufferPtr[1] != 1u || bufferPtr[2] != 6u || bufferPtr[3] != 7u)
1151 {
1152 log << tcu::TestLog::Message << "Buffer values were expected to be [0, 1, 6, 7], but were[" << bufferPtr[0] << ", " << bufferPtr[1] << ", " << bufferPtr[2] << ", " << bufferPtr[3] << ", " << "]" << tcu::TestLog::EndMessage;
1153 return tcu::TestStatus::fail("Fail");
1154 }
1155 }
1156
1157 return tcu::TestStatus::pass("pass");
1158 }
1159
1160 class MeshShaderObjectBindingCase : public vkt::TestCase
1161 {
1162 public:
MeshShaderObjectBindingCase(tcu::TestContext & testCtx,const std::string & name,const MeshBindingDrawParams & params)1163 MeshShaderObjectBindingCase (tcu::TestContext& testCtx, const std::string& name, const MeshBindingDrawParams& params)
1164 : vkt::TestCase (testCtx, name)
1165 , m_params (params)
1166 {}
~MeshShaderObjectBindingCase(void)1167 virtual ~MeshShaderObjectBindingCase (void) {}
1168
1169 void checkSupport (vkt::Context& context) const override;
1170 virtual void initPrograms (vk::SourceCollections& programCollection) const override;
createInstance(Context & context) const1171 TestInstance* createInstance (Context& context) const override { return new MeshShaderObjectBindingInstance(context, m_params); }
1172 private:
1173 MeshBindingDrawParams m_params;
1174 };
1175
checkSupport(vkt::Context & context) const1176 void MeshShaderObjectBindingCase::checkSupport (vkt::Context& context) const
1177 {
1178 context.requireDeviceFunctionality("VK_EXT_shader_object");
1179 context.requireDeviceFunctionality("VK_EXT_mesh_shader");
1180 const auto& features = context.getMeshShaderFeaturesEXT();
1181 if (!features.taskShader)
1182 TCU_THROW(NotSupportedError, "Task shaders not supported");
1183 if (!features.meshShader)
1184 TCU_THROW(NotSupportedError, "Mesh shaders not supported");
1185 }
1186
initPrograms(vk::SourceCollections & programCollection) const1187 void MeshShaderObjectBindingCase::initPrograms (vk::SourceCollections& programCollection) const
1188 {
1189 std::stringstream task1;
1190 std::stringstream task2;
1191 std::stringstream mesh1;
1192 std::stringstream mesh2;
1193 std::stringstream frag;
1194
1195 task1
1196 << "#version 450\n"
1197 << "#extension GL_EXT_mesh_shader : enable\n"
1198 << "layout (local_size_x=1, local_size_y=1, local_size_z=1) in;\n"
1199 << "layout(set = 0, binding = 0) buffer Output {\n"
1200 << " uint values[4];\n"
1201 << "} buffer_out;\n\n"
1202 << "void main ()\n"
1203 << "{\n"
1204 << " buffer_out.values[0] = 0u;\n"
1205 << " buffer_out.values[1] = 1u;\n"
1206 << " EmitMeshTasksEXT(1u, 1u, 1u);\n"
1207 << "}\n";
1208
1209 task2
1210 << "#version 450\n"
1211 << "#extension GL_EXT_mesh_shader : enable\n"
1212 << "layout (local_size_x=1, local_size_y=1, local_size_z=1) in;\n"
1213 << "layout(set = 0, binding = 0) buffer Output {\n"
1214 << " uint values[4];\n"
1215 << "} buffer_out;\n\n"
1216 << "void main ()\n"
1217 << "{\n"
1218 << " buffer_out.values[0] = 4u;\n"
1219 << " buffer_out.values[1] = 5u;\n"
1220 << " EmitMeshTasksEXT(1u, 1u, 1u);\n"
1221 << "}\n";
1222
1223 mesh1
1224 << "#version 460\n"
1225 << "#extension GL_EXT_mesh_shader : require\n"
1226 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1227 << "layout(max_vertices = 3) out;\n"
1228 << "layout(max_primitives = 1) out;\n"
1229 << "layout(triangles) out;\n"
1230 << "layout(set = 0, binding = 0) buffer Output {\n"
1231 << " uint values[4];\n"
1232 << "} buffer_out;\n\n"
1233 << "void main() {\n"
1234 << " SetMeshOutputsEXT(3, 1);\n"
1235 << " gl_MeshVerticesEXT[0].gl_Position = vec4(-1.0, -1.0, 0.0f, 1.0f);\n"
1236 << " gl_MeshVerticesEXT[1].gl_Position = vec4( 3.0, -1.0, 0.0f, 1.0f);\n"
1237 << " gl_MeshVerticesEXT[2].gl_Position = vec4(-1.0, 3.0, 0.0f, 1.0f);\n"
1238 << " gl_PrimitiveTriangleIndicesEXT[0] = uvec3(0, 1, 2);\n"
1239 << " buffer_out.values[2] = 2u;\n"
1240 << " buffer_out.values[3] = 3u;\n"
1241 << "}\n";
1242
1243 mesh2
1244 << "#version 460\n"
1245 << "#extension GL_EXT_mesh_shader : require\n"
1246 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1247 << "layout(max_vertices = 3) out;\n"
1248 << "layout(max_primitives = 1) out;\n"
1249 << "layout(triangles) out;\n"
1250 << "layout(set = 0, binding = 0) buffer Output {\n"
1251 << " uint values[4];\n"
1252 << "} buffer_out;\n\n"
1253 << "void main() {\n"
1254 << " SetMeshOutputsEXT(3, 1);\n"
1255 << " gl_MeshVerticesEXT[0].gl_Position = vec4(-1.0, -1.0, 0.0f, 1.0f);\n"
1256 << " gl_MeshVerticesEXT[1].gl_Position = vec4( 3.0, -1.0, 0.0f, 1.0f);\n"
1257 << " gl_MeshVerticesEXT[2].gl_Position = vec4(-1.0, 3.0, 0.0f, 1.0f);\n"
1258 << " gl_PrimitiveTriangleIndicesEXT[0] = uvec3(0, 1, 2);\n"
1259 << " buffer_out.values[2] = 6u;\n"
1260 << " buffer_out.values[3] = 7u;\n"
1261 << "}\n";
1262
1263 frag
1264 << "#version 450\n"
1265 << "layout (location=0) out vec4 outColor;\n"
1266 << "void main() {\n"
1267 << " outColor = vec4(1.0f);\n"
1268 << "}\n";
1269
1270 programCollection.glslSources.add("task1") << glu::TaskSource(task1.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1271 programCollection.glslSources.add("task2") << glu::TaskSource(task2.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1272 programCollection.glslSources.add("mesh1") << glu::MeshSource(mesh1.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1273 programCollection.glslSources.add("mesh2") << glu::MeshSource(mesh2.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1274 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
1275 }
1276
1277 class ShaderObjectBindingCase : public vkt::TestCase
1278 {
1279 public:
ShaderObjectBindingCase(tcu::TestContext & testCtx,const std::string & name,const BindingParams & params)1280 ShaderObjectBindingCase (tcu::TestContext& testCtx, const std::string& name, const BindingParams& params)
1281 : vkt::TestCase (testCtx, name)
1282 , m_params (params)
1283 {}
~ShaderObjectBindingCase(void)1284 virtual ~ShaderObjectBindingCase (void) {}
1285
1286 void checkSupport (vkt::Context& context) const override;
1287 virtual void initPrograms (vk::SourceCollections& programCollection) const override;
createInstance(Context & context) const1288 TestInstance* createInstance (Context& context) const override { return new ShaderObjectBindingInstance(context, m_params); }
1289 private:
1290 BindingParams m_params;
1291 };
1292
checkSupport(Context & context) const1293 void ShaderObjectBindingCase::checkSupport (Context& context) const
1294 {
1295 context.requireDeviceFunctionality("VK_EXT_shader_object");
1296 if (m_params.useMeshShaders)
1297 context.requireDeviceFunctionality("VK_EXT_mesh_shader");
1298 }
1299
initPrograms(vk::SourceCollections & programCollection) const1300 void ShaderObjectBindingCase::initPrograms (vk::SourceCollections& programCollection) const
1301 {
1302 vk::addBasicShaderObjectShaders(programCollection);
1303
1304 if (m_params.useMeshShaders)
1305 {
1306 std::stringstream task;
1307 std::stringstream mesh;
1308
1309 task
1310 << "#version 450\n"
1311 << "#extension GL_EXT_mesh_shader : enable\n"
1312 << "layout (local_size_x=1, local_size_y=1, local_size_z=1) in;\n"
1313 << "void main ()\n"
1314 << "{\n"
1315 << " EmitMeshTasksEXT(1u, 1u, 1u);\n"
1316 << "}\n";
1317
1318 mesh
1319 << "#version 460\n"
1320 << "#extension GL_EXT_mesh_shader : require\n"
1321 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1322 << "layout(max_vertices = 3) out;\n"
1323 << "layout(max_primitives = 1) out;\n"
1324 << "layout(triangles) out;\n"
1325 << "layout(set = 0, binding = 0) buffer Output {\n"
1326 << " uint values[4];\n"
1327 << "} buffer_out;\n\n"
1328 << "void main() {\n"
1329 << " SetMeshOutputsEXT(3, 1);\n"
1330 << " gl_MeshVerticesEXT[0].gl_Position = vec4(-1.0, -1.0, 0.0f, 1.0f);\n"
1331 << " gl_MeshVerticesEXT[1].gl_Position = vec4( 3.0, -1.0, 0.0f, 1.0f);\n"
1332 << " gl_MeshVerticesEXT[2].gl_Position = vec4(-1.0, 3.0, 0.0f, 1.0f);\n"
1333 << " gl_PrimitiveTriangleIndicesEXT[0] = uvec3(0, 1, 2);\n"
1334 << " buffer_out.values[0] = 0u;\n"
1335 << " buffer_out.values[1] = 1u;\n"
1336 << " buffer_out.values[2] = 2u;\n"
1337 << " buffer_out.values[3] = 3u;\n"
1338 << "}\n";
1339
1340 programCollection.glslSources.add("task") << glu::TaskSource(task.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1341 programCollection.glslSources.add("mesh") << glu::MeshSource(mesh.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1342 }
1343 }
1344
1345 }
1346
1347
createShaderObjectBindingTests(tcu::TestContext & testCtx)1348 tcu::TestCaseGroup* createShaderObjectBindingTests (tcu::TestContext& testCtx)
1349 {
1350 de::MovePtr<tcu::TestCaseGroup> bindingGroup(new tcu::TestCaseGroup(testCtx, "binding"));
1351
1352 BindingDrawParams params;
1353 params.testType = PASSTHROUGH_GEOM;
1354 params.stage = vk::VK_SHADER_STAGE_GEOMETRY_BIT;
1355 params.unusedOutputs = vk::VK_SHADER_STAGE_TASK_BIT_EXT;
1356 params.binaryStage = vk::VK_SHADER_STAGE_TASK_BIT_EXT;
1357 params.bindUnsupported = false;
1358 params.setStateAfter = false;
1359 params.unbindWithNullpShaders = false;
1360
1361 bindingGroup->addChild(new ShaderObjectBindingDrawCase(testCtx, "unbind_passthrough_geom", params));
1362
1363 const struct
1364 {
1365 vk::VkShaderStageFlagBits stage;
1366 const char* name;
1367 } stageTest[] =
1368 {
1369 { vk::VK_SHADER_STAGE_VERTEX_BIT, "vert" },
1370 { vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "tesc" },
1371 { vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "tese" },
1372 { vk::VK_SHADER_STAGE_GEOMETRY_BIT, "geom" },
1373 { vk::VK_SHADER_STAGE_FRAGMENT_BIT, "frag" },
1374 };
1375 params.testType = SWAP;
1376 for (const auto& stage : stageTest)
1377 {
1378 params.stage = stage.stage;
1379 params.unusedOutputs = vk::VK_SHADER_STAGE_ALL; // Unused
1380 params.binaryStage = vk::VK_SHADER_STAGE_ALL; // Unused
1381 params.setStateAfter = false;
1382 std::string name = "swap_" + std::string(stage.name);
1383 bindingGroup->addChild(new ShaderObjectBindingDrawCase(testCtx, name.c_str(), params));
1384 for (const auto& unusedOutputs : stageTest)
1385 {
1386 for (const auto& binaryStage : stageTest)
1387 {
1388 for (deUint32 i = 0; i < 2; ++i)
1389 {
1390 params.stage = stage.stage;
1391 params.unusedOutputs = unusedOutputs.stage;
1392 params.binaryStage = binaryStage.stage;
1393 params.setStateAfter = (bool)i;
1394 std::string name2 = "swap_" + std::string(stage.name) + "_unused_output_" + std::string(unusedOutputs.name) + "_binary_" + std::string(binaryStage.name) + "_" + ((i == 0) ? "before" : "after");
1395 bindingGroup->addChild(new ShaderObjectBindingDrawCase(testCtx, name2.c_str(), params));
1396 }
1397 }
1398 }
1399 }
1400
1401 params.unusedOutputs = vk::VK_SHADER_STAGE_ALL;
1402 params.binaryStage = vk::VK_SHADER_STAGE_ALL;
1403
1404 const struct
1405 {
1406 vk::VkShaderStageFlagBits stage;
1407 const char* name;
1408 } unbindStageTest[] =
1409 {
1410 { vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "tesc" },
1411 { vk::VK_SHADER_STAGE_GEOMETRY_BIT, "geom" },
1412 };
1413 params.testType = UNBIND;
1414 params.setStateAfter = false;
1415 for (const auto& stage : unbindStageTest)
1416 {
1417 for (deUint32 i = 0; i < 2; ++i)
1418 {
1419 params.stage = stage.stage;
1420 params.unbindWithNullpShaders = (bool)i;
1421 std::string name = "unbind_" + std::string(stage.name) + (params.unbindWithNullpShaders ? "_null_pshaders" : "_null_handle");
1422 bindingGroup->addChild(new ShaderObjectBindingDrawCase(testCtx, name.c_str(), params));
1423 }
1424 }
1425
1426 const struct
1427 {
1428 vk::VkShaderStageFlagBits stage;
1429 const char* name;
1430 } meshStageTest[] =
1431 {
1432 { vk::VK_SHADER_STAGE_TASK_BIT_EXT, "task" },
1433 { vk::VK_SHADER_STAGE_MESH_BIT_EXT, "mesh" },
1434 };
1435
1436 for (const auto& stage : meshStageTest)
1437 {
1438 MeshBindingDrawParams meshParams;
1439 meshParams.stage = stage.stage;
1440 std::string name = "mesh_swap_" + std::string(stage.name);
1441 bindingGroup->addChild(new MeshShaderObjectBindingCase(testCtx, name.c_str(), meshParams));
1442 }
1443
1444 params.testType = DISABLED;
1445 params.stage = vk::VK_SHADER_STAGE_GEOMETRY_BIT;
1446 bindingGroup->addChild(new ShaderObjectBindingDrawCase(testCtx, "disabled_geom", params));
1447 params.stage = vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
1448 bindingGroup->addChild(new ShaderObjectBindingDrawCase(testCtx, "disabled_tess", params));
1449 params.stage = vk::VK_SHADER_STAGE_GEOMETRY_BIT;
1450 params.bindUnsupported = true;
1451 bindingGroup->addChild(new ShaderObjectBindingDrawCase(testCtx, "disabled_geom_bind", params));
1452 params.stage = vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
1453 bindingGroup->addChild(new ShaderObjectBindingDrawCase(testCtx, "disabled_tess_bind", params));
1454 params.testType = DRAW_DISPATCH_DRAW;
1455 bindingGroup->addChild(new ShaderObjectBindingDrawCase(testCtx, "draw_dispatch_draw", params));
1456 params.testType = DISPATCH_DRAW_DISPATCH;
1457 bindingGroup->addChild(new ShaderObjectBindingDrawCase(testCtx, "dispatch_draw_dispatch", params));
1458
1459 BindingParams bindingParams;
1460 bindingParams.useMeshShaders = false;
1461 bindingGroup->addChild(new ShaderObjectBindingCase(testCtx, "bindings", bindingParams));
1462 bindingParams.useMeshShaders = true;
1463 bindingGroup->addChild(new ShaderObjectBindingCase(testCtx, "bindings_mesh_shaders", bindingParams));
1464
1465 return bindingGroup.release();
1466 }
1467
1468 } // ShaderObject
1469 } // vkt
1470