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 Pipeline Interaction Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktShaderObjectCreateTests.hpp"
26 #include "deUniquePtr.hpp"
27 #include "tcuTestCase.hpp"
28 #include "vktTestCase.hpp"
29 #include "vkCmdUtil.hpp"
30 #include "vkImageUtil.hpp"
31 #include "vkBarrierUtil.hpp"
32 #include "vktShaderObjectCreateUtil.hpp"
33 #include "vkObjUtil.hpp"
34 #include "deRandom.hpp"
35 #include "vkBuilderUtil.hpp"
36
37 namespace vkt
38 {
39 namespace ShaderObject
40 {
41
42 namespace
43 {
44
45 enum TestType
46 {
47 SHADER_OBJECT = 0,
48 MAX_PIPELINE,
49 MAX_PIPELINE_SHADER_OBJECT_MAX_PIPELINE,
50 SHADER_OBJECT_MAX_PIPELINE_SHADER_OBJECT,
51 MIN_PIPELINE_SHADER_OBJECT,
52 RENDER_PASS_PIPELINE_SHADER_OBJECT,
53 RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN,
54 SHADER_OBJECT_MIN_PIPELINE,
55 COMPUTE_SHADER_OBJECT_MIN_PIPELINE,
56 SHADER_OBJECT_COMPUTE_PIPELINE,
57 };
58
59 struct TestParams
60 {
61 TestType testType;
62 };
63
64 struct StageTestParams
65 {
66 bool vertShader;
67 bool tessShader;
68 bool geomShader;
69 bool fragShader;
70 };
71
72 class ShaderObjectPipelineInteractionInstance : public vkt::TestInstance
73 {
74 public:
ShaderObjectPipelineInteractionInstance(Context & context,const TestParams & params)75 ShaderObjectPipelineInteractionInstance(Context &context, const TestParams ¶ms)
76 : vkt::TestInstance(context)
77 , m_params(params)
78 {
79 }
~ShaderObjectPipelineInteractionInstance(void)80 virtual ~ShaderObjectPipelineInteractionInstance(void)
81 {
82 }
83
84 tcu::TestStatus iterate(void) override;
85
86 private:
87 bool verifyImage(de::MovePtr<vk::BufferWithMemory> &outputBuffer, uint32_t drawCount);
88 uint32_t getDrawCount(void);
89 TestParams m_params;
90
91 const vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
92 const vk::VkRect2D renderArea = {{
93 0u,
94 0u,
95 },
96 {
97 32u,
98 32u,
99 }};
100 };
101
getDrawCount(void)102 uint32_t ShaderObjectPipelineInteractionInstance::getDrawCount(void)
103 {
104 switch (m_params.testType)
105 {
106 case SHADER_OBJECT:
107 return 1;
108 case MAX_PIPELINE:
109 return 1;
110 case MAX_PIPELINE_SHADER_OBJECT_MAX_PIPELINE:
111 return 3;
112 case SHADER_OBJECT_MAX_PIPELINE_SHADER_OBJECT:
113 return 3;
114 case MIN_PIPELINE_SHADER_OBJECT:
115 return 2;
116 case RENDER_PASS_PIPELINE_SHADER_OBJECT:
117 return 1;
118 case RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN:
119 return 1;
120 case SHADER_OBJECT_MIN_PIPELINE:
121 return 2;
122 case COMPUTE_SHADER_OBJECT_MIN_PIPELINE:
123 return 1;
124 case SHADER_OBJECT_COMPUTE_PIPELINE:
125 return 1;
126 }
127 return 0;
128 }
129
extensionEnabled(const std::vector<std::string> & deviceExtensions,const std::string & ext)130 bool extensionEnabled(const std::vector<std::string> &deviceExtensions, const std::string &ext)
131 {
132 return std::find(deviceExtensions.begin(), deviceExtensions.end(), ext) != deviceExtensions.end();
133 }
134
iterate(void)135 tcu::TestStatus ShaderObjectPipelineInteractionInstance::iterate(void)
136 {
137 const vk::DeviceInterface &vk = m_context.getDeviceInterface();
138 const vk::VkDevice device = m_context.getDevice();
139 const vk::VkQueue queue = m_context.getUniversalQueue();
140 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
141 auto &alloc = m_context.getDefaultAllocator();
142 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(
143 m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
144 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
145 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
146 const bool taskSupported = m_context.getMeshShaderFeatures().taskShader;
147 const bool meshSupported = m_context.getMeshShaderFeatures().meshShader;
148
149 const auto subresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
150
151 const vk::VkImageCreateInfo createInfo = {
152 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
153 DE_NULL, // const void* pNext
154 0u, // VkImageCreateFlags flags
155 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
156 colorAttachmentFormat, // VkFormat format
157 {renderArea.extent.width, renderArea.extent.height, 1}, // VkExtent3D extent
158 1u, // uint32_t mipLevels
159 1u, // uint32_t arrayLayers
160 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
161 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
162 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
163 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
164 0, // uint32_t queueFamilyIndexCount
165 DE_NULL, // const uint32_t* pQueueFamilyIndices
166 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
167 };
168
169 de::MovePtr<vk::ImageWithMemory> image = de::MovePtr<vk::ImageWithMemory>(
170 new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
171 const auto imageView =
172 vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
173
174 const vk::VkDeviceSize colorOutputBufferSize =
175 renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
176 de::MovePtr<vk::BufferWithMemory> colorOutputBuffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
177 vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT),
178 vk::MemoryRequirement::HostVisible));
179
180 const vk::VkCommandPoolCreateInfo cmdPoolInfo = {
181 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType
182 DE_NULL, // pNext
183 vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags
184 queueFamilyIndex, // queuefamilyindex
185 };
186
187 const vk::Move<vk::VkCommandPool> cmdPool(createCommandPool(vk, device, &cmdPoolInfo));
188 const vk::Move<vk::VkCommandBuffer> cmdBuffer(
189 allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
190 const vk::Move<vk::VkCommandBuffer> copyCmdBuffer(
191 allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
192
193 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
194 vk::DescriptorSetLayoutBuilder()
195 .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
196 .build(vk, device));
197
198 const vk::Unique<vk::VkDescriptorPool> descriptorPool(
199 vk::DescriptorPoolBuilder()
200 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
201 .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
202
203 const auto pipelineLayout = makePipelineLayout(vk, device);
204 const auto computePipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout.get());
205
206 const auto &binaries = m_context.getBinaryCollection();
207 const auto &vert1 = binaries.get("vert1");
208 const auto &vert2 = binaries.get("vert2");
209 const auto &vert3 = binaries.get("vert3");
210 const auto &tesc = binaries.get("tesc");
211 const auto &tese = binaries.get("tese");
212 const auto &geom = binaries.get("geom");
213 const auto &frag1 = binaries.get("frag1");
214 const auto &frag2 = binaries.get("frag2");
215 const auto &frag3 = binaries.get("frag3");
216 const auto &comp = binaries.get("comp");
217
218 // Todo
219 vk::VkDescriptorSetLayout layout = descriptorSetLayout.get();
220
221 vk::VkShaderCreateInfoEXT vertCreateInfo1 =
222 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, vert1, tessellationSupported, geometrySupported);
223 vk::VkShaderCreateInfoEXT vertCreateInfo2 =
224 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, vert2, tessellationSupported, geometrySupported);
225 vk::VkShaderCreateInfoEXT vertCreateInfo3 =
226 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, vert3, tessellationSupported, geometrySupported);
227 vk::VkShaderCreateInfoEXT tescCreateInfo = vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
228 tesc, tessellationSupported, geometrySupported);
229 vk::VkShaderCreateInfoEXT teseCreateInfo = vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
230 tese, tessellationSupported, geometrySupported);
231 vk::VkShaderCreateInfoEXT geomCreateInfo =
232 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_GEOMETRY_BIT, geom, tessellationSupported, geometrySupported);
233 vk::VkShaderCreateInfoEXT fragCreateInfo1 =
234 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, frag1, tessellationSupported, geometrySupported);
235 vk::VkShaderCreateInfoEXT fragCreateInfo2 =
236 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, frag2, tessellationSupported, geometrySupported);
237 vk::VkShaderCreateInfoEXT fragCreateInfo3 =
238 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, frag3, tessellationSupported, geometrySupported);
239 vk::VkShaderCreateInfoEXT compCreateInfo = vk::makeShaderCreateInfo(
240 vk::VK_SHADER_STAGE_COMPUTE_BIT, comp, tessellationSupported, geometrySupported, &layout);
241
242 vk::Move<vk::VkShaderEXT> vertShader1 = vk::createShader(vk, device, vertCreateInfo1);
243 vk::Move<vk::VkShaderEXT> vertShader2 = vk::createShader(vk, device, vertCreateInfo2);
244 vk::Move<vk::VkShaderEXT> vertShader3 = vk::createShader(vk, device, vertCreateInfo3);
245 vk::Move<vk::VkShaderEXT> tescShader = vk::createShader(vk, device, tescCreateInfo);
246 vk::Move<vk::VkShaderEXT> teseShader = vk::createShader(vk, device, teseCreateInfo);
247 vk::Move<vk::VkShaderEXT> geomShader = vk::createShader(vk, device, geomCreateInfo);
248 vk::Move<vk::VkShaderEXT> fragShader1 = vk::createShader(vk, device, fragCreateInfo1);
249 vk::Move<vk::VkShaderEXT> fragShader2 = vk::createShader(vk, device, fragCreateInfo2);
250 vk::Move<vk::VkShaderEXT> fragShader3 = vk::createShader(vk, device, fragCreateInfo3);
251 vk::Move<vk::VkShaderEXT> compShader = vk::createShader(vk, device, compCreateInfo);
252
253 const auto vertShaderModule1 = createShaderModule(vk, device, vert1);
254 const auto vertShaderModule2 = createShaderModule(vk, device, vert2);
255 const auto vertShaderModule3 = createShaderModule(vk, device, vert3);
256 const auto tescShaderModule = createShaderModule(vk, device, tesc);
257 const auto teseShaderModule = createShaderModule(vk, device, tese);
258 const auto geomShaderModule = createShaderModule(vk, device, geom);
259 const auto fragShaderModule1 = createShaderModule(vk, device, frag1);
260 const auto fragShaderModule2 = createShaderModule(vk, device, frag2);
261 const auto fragShaderModule3 = createShaderModule(vk, device, frag3);
262 const auto compShaderModule = createShaderModule(vk, device, comp);
263
264 const auto renderPass = vk::makeRenderPass(vk, device, colorAttachmentFormat, vk::VK_FORMAT_UNDEFINED,
265 vk::VK_ATTACHMENT_LOAD_OP_CLEAR, vk::VK_IMAGE_LAYOUT_GENERAL);
266 const auto framebuffer = vk::makeFramebuffer(vk, device, *renderPass, 1u, &*imageView, renderArea.extent.width,
267 renderArea.extent.height);
268
269 const vk::VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
270 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
271 DE_NULL, // const void* pNext;
272 0u, // VkPipelineVertexInputStateCreateFlags flags;
273 0u, // uint32_t vertexBindingDescriptionCount;
274 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
275 0u, // uint32_t vertexAttributeDescriptionCount;
276 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
277 };
278
279 const vk::VkPipelineTessellationStateCreateInfo tessStateCreateInfo = {
280 vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
281 DE_NULL, // const void* pNext;
282 0u, // VkPipelineTessellationStateCreateFlags flags;
283 4u, // uint32_t patchControlPoints;
284 };
285
286 const vk::VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo = {
287 vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
288 DE_NULL, // const void* pNext;
289 (vk::VkPipelineInputAssemblyStateCreateFlags)0u, // VkPipelineInputAssemblyStateCreateFlags flags;
290 vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, // VkPrimitiveTopology topology;
291 VK_FALSE, // VkBool32 primitiveRestartEnable;
292 };
293
294 vk::VkPipelineRenderingCreateInfo pipelineRenderingCreateInfo = {
295 vk::VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, // VkStructureType sType
296 DE_NULL, // const void* pNext
297 0u, // uint32_t viewMask
298 1u, // uint32_t colorAttachmentCount
299 &colorAttachmentFormat, // const VkFormat* pColorAttachmentFormats
300 vk::VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat
301 vk::VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat
302 };
303
304 const vk::VkViewport viewport = vk::makeViewport(renderArea.extent);
305 const vk::VkRect2D scissor = vk::makeRect2D(renderArea.extent);
306
307 bool createDynamicPipeline = m_params.testType != MIN_PIPELINE_SHADER_OBJECT &&
308 m_params.testType != SHADER_OBJECT_MIN_PIPELINE &&
309 m_params.testType != COMPUTE_SHADER_OBJECT_MIN_PIPELINE &&
310 m_params.testType != RENDER_PASS_PIPELINE_SHADER_OBJECT &&
311 m_params.testType != RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN;
312
313 const vk::VkPipelineViewportStateCreateInfo viewportStateCreateInfo = {
314 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType
315 DE_NULL, // const void* pNext
316 (vk::VkPipelineViewportStateCreateFlags)0u, // VkPipelineViewportStateCreateFlags flags
317 createDynamicPipeline ? 0u : 1u, // uint32_t viewportCount
318 &viewport, // const VkViewport* pViewports
319 createDynamicPipeline ? 0u : 1u, // uint32_t scissorCount
320 &scissor, // const VkRect2D* pScissors
321 };
322
323 const auto &edsFeatures = m_context.getExtendedDynamicStateFeaturesEXT();
324 const auto &eds2Features = m_context.getExtendedDynamicState2FeaturesEXT();
325 const auto &eds3Features = m_context.getExtendedDynamicState3FeaturesEXT();
326 const auto &viFeatures = m_context.getVertexInputDynamicStateFeaturesEXT();
327
328 std::vector<vk::VkDynamicState> dynamicStates = {
329 vk::VK_DYNAMIC_STATE_LINE_WIDTH, vk::VK_DYNAMIC_STATE_DEPTH_BIAS,
330 vk::VK_DYNAMIC_STATE_BLEND_CONSTANTS, vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS,
331 vk::VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, vk::VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
332 vk::VK_DYNAMIC_STATE_STENCIL_REFERENCE,
333 };
334
335 if (edsFeatures.extendedDynamicState)
336 {
337 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CULL_MODE_EXT);
338 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_FRONT_FACE_EXT);
339 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT);
340 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT);
341 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT);
342 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT);
343 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT);
344 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT);
345 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT);
346 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT);
347 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT);
348 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_OP_EXT);
349 }
350 else
351 {
352 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT);
353 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SCISSOR);
354 }
355 if (eds2Features.extendedDynamicState2)
356 {
357 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE);
358 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE);
359 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE);
360 }
361 if (eds2Features.extendedDynamicState2LogicOp)
362 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LOGIC_OP_EXT);
363 if (eds2Features.extendedDynamicState2PatchControlPoints)
364 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT);
365
366 if (eds3Features.extendedDynamicState3TessellationDomainOrigin)
367 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT);
368 if (eds3Features.extendedDynamicState3DepthClampEnable)
369 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT);
370 if (eds3Features.extendedDynamicState3PolygonMode)
371 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT);
372 if (eds3Features.extendedDynamicState3RasterizationSamples)
373 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT);
374 if (eds3Features.extendedDynamicState3SampleMask)
375 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_MASK_EXT);
376 if (eds3Features.extendedDynamicState3AlphaToCoverageEnable)
377 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT);
378 if (eds3Features.extendedDynamicState3AlphaToOneEnable)
379 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT);
380 if (eds3Features.extendedDynamicState3LogicOpEnable)
381 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT);
382 if (eds3Features.extendedDynamicState3ColorBlendEnable)
383 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT);
384 if (eds3Features.extendedDynamicState3ColorBlendEquation)
385 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT);
386 if (eds3Features.extendedDynamicState3ColorWriteMask)
387 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT);
388 if (viFeatures.vertexInputDynamicState)
389 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT);
390
391 if (extensionEnabled(deviceExtensions, "VK_EXT_transform_feedback") &&
392 eds3Features.extendedDynamicState3RasterizationStream)
393 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT);
394 if (extensionEnabled(deviceExtensions, "VK_EXT_blend_operation_advanced") &&
395 eds3Features.extendedDynamicState3ColorBlendAdvanced)
396 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT);
397 if (extensionEnabled(deviceExtensions, "VK_EXT_conservative_rasterization") &&
398 eds3Features.extendedDynamicState3ConservativeRasterizationMode)
399 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT);
400 if (extensionEnabled(deviceExtensions, "VK_NV_framebuffer_mixed_samples") &&
401 eds3Features.extendedDynamicState3CoverageModulationMode)
402 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV);
403 if (extensionEnabled(deviceExtensions, "VK_NV_framebuffer_mixed_samples") &&
404 eds3Features.extendedDynamicState3CoverageModulationTableEnable)
405 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV);
406 if (extensionEnabled(deviceExtensions, "VK_NV_framebuffer_mixed_samples") &&
407 eds3Features.extendedDynamicState3CoverageModulationTable)
408 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV);
409 if (extensionEnabled(deviceExtensions, "VK_NV_coverage_reduction_mode") &&
410 eds3Features.extendedDynamicState3CoverageReductionMode)
411 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV);
412 if (extensionEnabled(deviceExtensions, "VK_NV_fragment_coverage_to_color") &&
413 eds3Features.extendedDynamicState3CoverageToColorEnable)
414 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV);
415 if (extensionEnabled(deviceExtensions, "VK_NV_fragment_coverage_to_color") &&
416 eds3Features.extendedDynamicState3CoverageToColorLocation)
417 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV);
418 if (extensionEnabled(deviceExtensions, "VK_EXT_depth_clip_enable") &&
419 eds3Features.extendedDynamicState3DepthClipEnable)
420 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT);
421 if (extensionEnabled(deviceExtensions, "VK_EXT_depth_clip_control") &&
422 eds3Features.extendedDynamicState3DepthClipNegativeOneToOne)
423 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT);
424 if (extensionEnabled(deviceExtensions, "VK_EXT_color_write_enable"))
425 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT);
426 if (extensionEnabled(deviceExtensions, "VK_EXT_conservative_rasterization") &&
427 eds3Features.extendedDynamicState3ExtraPrimitiveOverestimationSize)
428 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT);
429 if ((extensionEnabled(deviceExtensions, "VK_KHR_line_rasterization") ||
430 extensionEnabled(deviceExtensions, "VK_EXT_line_rasterization")) &&
431 eds3Features.extendedDynamicState3LineRasterizationMode)
432 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT);
433 if ((extensionEnabled(deviceExtensions, "VK_KHR_line_rasterization") ||
434 extensionEnabled(deviceExtensions, "VK_EXT_line_rasterization")) &&
435 eds3Features.extendedDynamicState3LineStippleEnable)
436 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT);
437 if ((extensionEnabled(deviceExtensions, "VK_KHR_line_rasterization") ||
438 extensionEnabled(deviceExtensions, "VK_EXT_line_rasterization")))
439 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_EXT);
440 if (extensionEnabled(deviceExtensions, "VK_EXT_provoking_vertex") &&
441 eds3Features.extendedDynamicState3ProvokingVertexMode)
442 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT);
443 if (extensionEnabled(deviceExtensions, "VK_KHR_fragment_shading_rate"))
444 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR);
445 if (extensionEnabled(deviceExtensions, "VK_NV_representative_fragment_test") &&
446 eds3Features.extendedDynamicState3RepresentativeFragmentTestEnable)
447 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV);
448 if (extensionEnabled(deviceExtensions, "VK_EXT_sample_locations") &&
449 eds3Features.extendedDynamicState3SampleLocationsEnable)
450 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT);
451 if (extensionEnabled(deviceExtensions, "VK_EXT_sample_locations"))
452 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT);
453 if (extensionEnabled(deviceExtensions, "VK_NV_shading_rate_image") &&
454 eds3Features.extendedDynamicState3ShadingRateImageEnable)
455 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV);
456 if (extensionEnabled(deviceExtensions, "VK_NV_shading_rate_image"))
457 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV);
458 if (extensionEnabled(deviceExtensions, "VK_NV_shading_rate_image"))
459 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV);
460 if (extensionEnabled(deviceExtensions, "VK_NV_viewport_swizzle") &&
461 eds3Features.extendedDynamicState3ViewportSwizzle)
462 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV);
463 if (extensionEnabled(deviceExtensions, "VK_NV_clip_space_w_scaling") &&
464 eds3Features.extendedDynamicState3ViewportWScalingEnable)
465 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV);
466 if (extensionEnabled(deviceExtensions, "VK_NV_clip_space_w_scaling"))
467 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV);
468 if (extensionEnabled(deviceExtensions, "VK_NV_scissor_exclusive"))
469 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV);
470 if (extensionEnabled(deviceExtensions, "VK_EXT_discard_rectangles"))
471 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT);
472 if (extensionEnabled(deviceExtensions, "VK_EXT_discard_rectangles"))
473 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT);
474 if (extensionEnabled(deviceExtensions, "VK_EXT_discard_rectangles"))
475 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT);
476
477 const vk::VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = {
478 vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
479 DE_NULL, // const void* pNext;
480 (vk::VkPipelineDynamicStateCreateFlags)0u, // VkPipelineDynamicStateCreateFlags flags;
481 static_cast<uint32_t>(dynamicStates.size()), // uint32_t dynamicStateCount;
482 dynamicStates.data(), // const VkDynamicState* pDynamicStates;
483 };
484 const vk::VkPipelineDynamicStateCreateInfo *pipelineDynamicState =
485 (createDynamicPipeline) ? &dynamicStateCreateInfo : DE_NULL;
486
487 const vk::VkDeviceSize bufferSizeBytes = sizeof(uint32_t) * 4;
488
489 const vk::Unique<vk::VkDescriptorSet> descriptorSet(
490 makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
491 const vk::BufferWithMemory outputBuffer(
492 vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
493 vk::MemoryRequirement::HostVisible);
494
495 const vk::VkDescriptorBufferInfo descriptorInfo =
496 vk::makeDescriptorBufferInfo(*outputBuffer, 0ull, bufferSizeBytes);
497 vk::DescriptorSetUpdateBuilder()
498 .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u),
499 vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
500 .update(vk, device);
501
502 vk::VkPipelineRenderingCreateInfo *pPipelineRenderingCreateInfo = &pipelineRenderingCreateInfo;
503 vk::VkRenderPass renderPassHandle = VK_NULL_HANDLE;
504 if (m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT ||
505 m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN)
506 {
507 pPipelineRenderingCreateInfo = DE_NULL;
508 renderPassHandle = *renderPass;
509 }
510
511 const auto pipeline1 = makeGraphicsPipeline(
512 vk, device, pipelineLayout.get(), vertShaderModule1.get(), tescShaderModule.get(), teseShaderModule.get(),
513 geomShaderModule.get(), fragShaderModule1.get(), renderPassHandle, 0u, &vertexInputStateParams,
514 &pipelineInputAssemblyStateInfo, &tessStateCreateInfo, &viewportStateCreateInfo, DE_NULL, DE_NULL, DE_NULL,
515 DE_NULL, pipelineDynamicState, pPipelineRenderingCreateInfo);
516 const auto pipeline2 = makeGraphicsPipeline(
517 vk, device, pipelineLayout.get(), vertShaderModule2.get(), tescShaderModule.get(), teseShaderModule.get(),
518 geomShaderModule.get(), fragShaderModule2.get(), renderPassHandle, 0u, &vertexInputStateParams,
519 &pipelineInputAssemblyStateInfo, &tessStateCreateInfo, &viewportStateCreateInfo, DE_NULL, DE_NULL, DE_NULL,
520 DE_NULL, pipelineDynamicState, pPipelineRenderingCreateInfo);
521 const auto pipeline3 = makeGraphicsPipeline(
522 vk, device, pipelineLayout.get(), vertShaderModule3.get(), tescShaderModule.get(), teseShaderModule.get(),
523 geomShaderModule.get(), fragShaderModule3.get(), renderPassHandle, 0u, &vertexInputStateParams,
524 &pipelineInputAssemblyStateInfo, &tessStateCreateInfo, &viewportStateCreateInfo, DE_NULL, DE_NULL, DE_NULL,
525 DE_NULL, pipelineDynamicState, pPipelineRenderingCreateInfo);
526 const auto computePipeline =
527 vk::makeComputePipeline(vk, device, computePipelineLayout.get(), compShaderModule.get());
528
529 const vk::VkClearValue clearValue = vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 1.0f});
530 vk::VkImageMemoryBarrier initialBarrier =
531 vk::makeImageMemoryBarrier(0, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
532 vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
533
534 const vk::VkDeviceSize bufferSize = 64;
535 de::MovePtr<vk::BufferWithMemory> buffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
536 vk, device, alloc, vk::makeBufferCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
537 vk::MemoryRequirement::HostVisible));
538
539 vk::beginCommandBuffer(vk, *cmdBuffer, 0u);
540
541 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
542 vk::VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0, DE_NULL, 0, DE_NULL, 1,
543 &initialBarrier);
544
545 if (m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT)
546 {
547 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
548 }
549
550 if (m_params.testType != COMPUTE_SHADER_OBJECT_MIN_PIPELINE && m_params.testType != SHADER_OBJECT_COMPUTE_PIPELINE)
551 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL,
552 vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
553
554 vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,
555 false,
556 !m_context.getExtendedDynamicStateFeaturesEXT().extendedDynamicState);
557 vk::bindNullTaskMeshShaders(vk, *cmdBuffer, m_context.getMeshShaderFeaturesEXT());
558
559 vk::VkDeviceSize offset = 0u;
560 vk::VkDeviceSize stride = 16u;
561 vk.cmdBindVertexBuffers2(*cmdBuffer, 0u, 1u, &**buffer, &offset, &bufferSize, &stride);
562
563 if (m_params.testType == SHADER_OBJECT)
564 {
565 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1,
566 taskSupported, meshSupported);
567 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
568 }
569 else if (m_params.testType == MAX_PIPELINE)
570 {
571 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
572 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
573 }
574 else if (m_params.testType == MAX_PIPELINE_SHADER_OBJECT_MAX_PIPELINE)
575 {
576 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
577 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
578
579 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader2, *tescShader, *teseShader, *geomShader, *fragShader2,
580 taskSupported, meshSupported);
581 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
582
583 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline3);
584 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
585 }
586 else if (m_params.testType == SHADER_OBJECT_MAX_PIPELINE_SHADER_OBJECT)
587 {
588 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1,
589 taskSupported, meshSupported);
590 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
591
592 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline2);
593 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
594
595 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader3, *tescShader, *teseShader, *geomShader, *fragShader3,
596 taskSupported, meshSupported);
597 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
598 }
599 else if (m_params.testType == MIN_PIPELINE_SHADER_OBJECT)
600 {
601 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
602 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
603
604 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader2, *tescShader, *teseShader, *geomShader, *fragShader2,
605 taskSupported, meshSupported);
606 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
607 }
608 else if (m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT)
609 {
610 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1,
611 taskSupported, meshSupported);
612 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
613 }
614 else if (m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN)
615 {
616 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
617 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1,
618 taskSupported, meshSupported);
619 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
620 }
621 else if (m_params.testType == SHADER_OBJECT_MIN_PIPELINE)
622 {
623 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1,
624 taskSupported, meshSupported);
625 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
626
627 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline2);
628 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
629 }
630 else if (m_params.testType == COMPUTE_SHADER_OBJECT_MIN_PIPELINE)
631 {
632 vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, computePipelineLayout.get(), 0, 1,
633 &descriptorSet.get(), 0, DE_NULL);
634
635 vk::VkShaderStageFlagBits stages[] = {vk::VK_SHADER_STAGE_COMPUTE_BIT};
636 vk.cmdBindShadersEXT(*cmdBuffer, 1, stages, &*compShader);
637 vk.cmdDispatch(*cmdBuffer, 4, 1, 1);
638
639 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL,
640 vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
641 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
642 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
643 vk::endRendering(vk, *cmdBuffer);
644 }
645 else if (m_params.testType == SHADER_OBJECT_COMPUTE_PIPELINE)
646 {
647 vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, computePipelineLayout.get(), 0, 1,
648 &descriptorSet.get(), 0, DE_NULL);
649
650 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL,
651 vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
652 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1,
653 taskSupported, meshSupported);
654 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
655 vk::endRendering(vk, *cmdBuffer);
656
657 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
658 vk.cmdDispatch(*cmdBuffer, 4, 1, 1);
659 }
660
661 if (m_params.testType != COMPUTE_SHADER_OBJECT_MIN_PIPELINE && m_params.testType != SHADER_OBJECT_COMPUTE_PIPELINE)
662 vk::endRendering(vk, *cmdBuffer);
663
664 vk::endCommandBuffer(vk, *cmdBuffer);
665
666 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
667
668 const vk::VkBufferImageCopy copyRegion = {
669 0u, // VkDeviceSize bufferOffset;
670 0u, // uint32_t bufferRowLength;
671 0u, // uint32_t bufferImageHeight;
672 {
673 vk::VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
674 0u, // uint32_t mipLevel;
675 0u, // uint32_t baseArrayLayer;
676 1u, // uint32_t layerCount;
677 }, // VkImageSubresourceLayers imageSubresource;
678 {0, 0, 0}, // VkOffset3D imageOffset;
679 {renderArea.extent.width, renderArea.extent.height, 1} // VkExtent3D imageExtent;
680 };
681
682 vk::beginCommandBuffer(vk, *copyCmdBuffer, 0u);
683 vk.cmdCopyImageToBuffer(*copyCmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u, ©Region);
684 vk::endCommandBuffer(vk, *copyCmdBuffer);
685 submitCommandsAndWait(vk, device, queue, copyCmdBuffer.get());
686
687 if (!verifyImage(colorOutputBuffer, getDrawCount()))
688 return tcu::TestStatus::fail("Fail");
689
690 if (m_params.testType == COMPUTE_SHADER_OBJECT_MIN_PIPELINE || m_params.testType == SHADER_OBJECT_COMPUTE_PIPELINE)
691 {
692 const vk::Allocation &outputBufferAllocation = outputBuffer.getAllocation();
693 invalidateAlloc(vk, device, outputBufferAllocation);
694
695 const uint32_t *bufferPtr = static_cast<uint32_t *>(outputBufferAllocation.getHostPtr());
696
697 for (uint32_t i = 0; i < 4; ++i)
698 {
699 if (bufferPtr[i] != i)
700 return tcu::TestStatus::fail("Fail");
701 }
702 }
703
704 return tcu::TestStatus::pass("Pass");
705 }
706
verifyImage(de::MovePtr<vk::BufferWithMemory> & outputBuffer,uint32_t drawCount)707 bool ShaderObjectPipelineInteractionInstance::verifyImage(de::MovePtr<vk::BufferWithMemory> &outputBuffer,
708 uint32_t drawCount)
709 {
710 tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(
711 vk::mapVkFormat(vk::VK_FORMAT_R8G8B8A8_UNORM), renderArea.extent.width, renderArea.extent.height, 1,
712 (const void *)outputBuffer->getAllocation().getHostPtr());
713
714 const tcu::Vec4 red = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
715 const tcu::Vec4 green = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
716 const tcu::Vec4 blue = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
717 const int32_t width = resultBuffer.getWidth();
718 const int32_t height = resultBuffer.getHeight();
719
720 for (int32_t j = 0; j < height; ++j)
721 {
722 for (int32_t i = 0; i < width; ++i)
723 {
724 const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
725 if (i < width / 2 && j < height / 2 && drawCount > 0)
726 {
727 if (color != red)
728 return false;
729 }
730 else if (i >= width / 2 && j < height / 2 && drawCount > 1)
731 {
732 if (color != green)
733 return false;
734 }
735 else if (i < width / 2 && j >= height / 2 && drawCount > 2)
736 {
737 if (color != blue)
738 return false;
739 }
740 }
741 }
742
743 return true;
744 }
745
746 class ShaderObjectPipelineInteractionCase : public vkt::TestCase
747 {
748 public:
ShaderObjectPipelineInteractionCase(tcu::TestContext & testCtx,const std::string & name,const TestParams & params)749 ShaderObjectPipelineInteractionCase(tcu::TestContext &testCtx, const std::string &name, const TestParams ¶ms)
750 : vkt::TestCase(testCtx, name)
751 , m_params(params)
752 {
753 }
~ShaderObjectPipelineInteractionCase(void)754 virtual ~ShaderObjectPipelineInteractionCase(void)
755 {
756 }
757
758 void checkSupport(vkt::Context &context) const override;
759 virtual void initPrograms(vk::SourceCollections &programCollection) const override;
createInstance(Context & context) const760 TestInstance *createInstance(Context &context) const override
761 {
762 return new ShaderObjectPipelineInteractionInstance(context, m_params);
763 }
764
765 private:
766 TestParams m_params;
767 };
768
initPrograms(vk::SourceCollections & programCollection) const769 void ShaderObjectPipelineInteractionCase::initPrograms(vk::SourceCollections &programCollection) const
770 {
771 std::stringstream vert1, vert2, vert3;
772 std::stringstream geom;
773 std::stringstream tesc;
774 std::stringstream tese;
775 std::stringstream frag1, frag2, frag3;
776 std::stringstream comp;
777
778 vert1 << "#version 450\n"
779 << "void main() {\n"
780 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
781 << " gl_Position = vec4(pos * 0.5f - vec2(0.5f, 0.5f), 0.0f, 1.0f);\n"
782 << "}\n";
783 vert2 << "#version 450\n"
784 << "void main() {\n"
785 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
786 << " gl_Position = vec4(pos * 0.5f - vec2(0.0f, 0.5f), 0.0f, 1.0f);\n"
787 << "}\n";
788 vert3 << "#version 450\n"
789 << "void main() {\n"
790 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
791 << " gl_Position = vec4(pos * 0.5f - vec2(0.5f, 0.0f), 0.0f, 1.0f);\n"
792 << "}\n";
793
794 tesc << "#version 450\n"
795 << "\n"
796 << "layout(vertices = 4) out;\n"
797 << "\n"
798 << "void main (void)\n"
799 << "{\n"
800 << " if (gl_InvocationID == 0) {\n"
801 << " gl_TessLevelInner[0] = 1.0;\n"
802 << " gl_TessLevelInner[1] = 1.0;\n"
803 << " gl_TessLevelOuter[0] = 1.0;\n"
804 << " gl_TessLevelOuter[1] = 1.0;\n"
805 << " gl_TessLevelOuter[2] = 1.0;\n"
806 << " gl_TessLevelOuter[3] = 1.0;\n"
807 << " }\n"
808 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
809 << "}\n";
810
811 tese << "#version 450\n"
812 << "\n"
813 << "layout(quads, equal_spacing) in;\n"
814 << "\n"
815 << "void main (void)\n"
816 << "{\n"
817 << " float u = gl_TessCoord.x;\n"
818 << " float v = gl_TessCoord.y;\n"
819 << " float omu = 1.0f - u;\n"
820 << " float omv = 1.0f - v;\n"
821 << " gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * "
822 "gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
823 << " gl_Position.x *= 2.0f;\n"
824 << "}\n";
825
826 geom << "#version 450\n"
827 << "layout(triangles) in;\n"
828 << "layout(triangle_strip, max_vertices = 4) out;\n"
829 << "\n"
830 << "void main(void)\n"
831 << "{\n"
832 << " gl_Position = gl_in[0].gl_Position;\n"
833 << " gl_Position.y *= 2.0f;\n"
834 << " EmitVertex();\n"
835 << " gl_Position = gl_in[1].gl_Position;\n"
836 << " gl_Position.y *= 2.0f;\n"
837 << " EmitVertex();\n"
838 << " gl_Position = gl_in[2].gl_Position;\n"
839 << " gl_Position.y *= 2.0f;\n"
840 << " EmitVertex();\n"
841 << " EndPrimitive();\n"
842 << "}\n";
843
844 frag1 << "#version 450\n"
845 << "layout (location=0) out vec4 outColor;\n"
846 << "void main() {\n"
847 << " outColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n"
848 << "}\n";
849 frag2 << "#version 450\n"
850 << "layout (location=0) out vec4 outColor;\n"
851 << "void main() {\n"
852 << " outColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n"
853 << "}\n";
854 frag3 << "#version 450\n"
855 << "layout (location=0) out vec4 outColor;\n"
856 << "void main() {\n"
857 << " outColor = vec4(0.0f, 0.0f, 1.0f, 1.0f);\n"
858 << "}\n";
859
860 comp << "#version 450\n"
861 << "layout(local_size_x=16, local_size_x=1, local_size_x=1) in;\n"
862 << "layout(binding = 0) buffer Output {\n"
863 << " uint values[16];\n"
864 << "} buffer_out;\n\n"
865 << "void main() {\n"
866 << " buffer_out.values[gl_LocalInvocationID.x] = gl_LocalInvocationID.x;\n"
867 << "}\n";
868
869 programCollection.glslSources.add("vert1") << glu::VertexSource(vert1.str());
870 programCollection.glslSources.add("vert2") << glu::VertexSource(vert2.str());
871 programCollection.glslSources.add("vert3") << glu::VertexSource(vert3.str());
872 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
873 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
874 programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
875 programCollection.glslSources.add("frag1") << glu::FragmentSource(frag1.str());
876 programCollection.glslSources.add("frag2") << glu::FragmentSource(frag2.str());
877 programCollection.glslSources.add("frag3") << glu::FragmentSource(frag3.str());
878 programCollection.glslSources.add("comp") << glu::ComputeSource(comp.str());
879 }
880
checkSupport(Context & context) const881 void ShaderObjectPipelineInteractionCase::checkSupport(Context &context) const
882 {
883 context.requireDeviceFunctionality("VK_EXT_shader_object");
884
885 context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
886 context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
887 }
888
889 class ShaderObjectStageBindingInstance : public vkt::TestInstance
890 {
891 public:
ShaderObjectStageBindingInstance(Context & context,const StageTestParams & params)892 ShaderObjectStageBindingInstance(Context &context, const StageTestParams ¶ms)
893 : vkt::TestInstance(context)
894 , m_params(params)
895 {
896 }
~ShaderObjectStageBindingInstance(void)897 virtual ~ShaderObjectStageBindingInstance(void)
898 {
899 }
900
901 tcu::TestStatus iterate(void) override;
902
903 private:
904 bool verifyImage(de::MovePtr<vk::BufferWithMemory> &outputBuffer);
905 StageTestParams m_params;
906
907 const vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
908 const vk::VkRect2D renderArea = {{
909 0u,
910 0u,
911 },
912 {
913 32u,
914 32u,
915 }};
916 };
917
iterate(void)918 tcu::TestStatus ShaderObjectStageBindingInstance::iterate(void)
919 {
920 const vk::DeviceInterface &vk = m_context.getDeviceInterface();
921 const vk::VkDevice device = m_context.getDevice();
922 const vk::VkQueue queue = m_context.getUniversalQueue();
923 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
924 auto &alloc = m_context.getDefaultAllocator();
925 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(
926 m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
927 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
928 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
929 const bool taskSupported = m_context.getMeshShaderFeatures().taskShader;
930 const bool meshSupported = m_context.getMeshShaderFeatures().meshShader;
931
932 const auto subresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
933
934 const vk::VkImageCreateInfo createInfo = {
935 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
936 DE_NULL, // const void* pNext
937 0u, // VkImageCreateFlags flags
938 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
939 colorAttachmentFormat, // VkFormat format
940 {renderArea.extent.width, renderArea.extent.height, 1}, // VkExtent3D extent
941 1u, // uint32_t mipLevels
942 1u, // uint32_t arrayLayers
943 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
944 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
945 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
946 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
947 0, // uint32_t queueFamilyIndexCount
948 DE_NULL, // const uint32_t* pQueueFamilyIndices
949 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
950 };
951
952 de::MovePtr<vk::ImageWithMemory> image = de::MovePtr<vk::ImageWithMemory>(
953 new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
954 const auto imageView =
955 vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
956
957 const vk::VkDeviceSize colorOutputBufferSize =
958 renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
959 de::MovePtr<vk::BufferWithMemory> colorOutputBuffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
960 vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT),
961 vk::MemoryRequirement::HostVisible));
962
963 const vk::VkCommandPoolCreateInfo cmdPoolInfo = {
964 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType
965 DE_NULL, // pNext
966 vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags
967 queueFamilyIndex, // queuefamilyindex
968 };
969
970 const vk::Move<vk::VkCommandPool> cmdPool(createCommandPool(vk, device, &cmdPoolInfo));
971 const vk::Move<vk::VkCommandBuffer> cmdBuffer(
972 allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
973 const vk::Move<vk::VkCommandBuffer> copyCmdBuffer(
974 allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
975
976 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
977 vk::DescriptorSetLayoutBuilder()
978 .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_ALL_GRAPHICS)
979 .build(vk, device));
980
981 const vk::Unique<vk::VkDescriptorPool> descriptorPool(
982 vk::DescriptorPoolBuilder()
983 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
984 .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
985
986 const auto topology =
987 m_params.tessShader ? vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
988
989 const auto pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout.get());
990 const auto emptyPipelineLayout = makePipelineLayout(vk, device);
991
992 const auto &binaries = m_context.getBinaryCollection();
993 const auto &vert = binaries.get("vert");
994 const auto &tesc = binaries.get("tesc");
995 const auto &tese = binaries.get("tese");
996 const auto &geom = binaries.get("geom");
997 const auto &frag = binaries.get("frag");
998
999 const auto &pipeline_vert = binaries.get("pipeline_vert");
1000 const auto &pipeline_tesc = binaries.get("pipeline_tesc");
1001 const auto &pipeline_tese = binaries.get("pipeline_tese");
1002 const auto &pipeline_geom = binaries.get("pipeline_geom");
1003 const auto &pipeline_frag = binaries.get("pipeline_frag");
1004
1005 vk::VkDescriptorSetLayout layout = descriptorSetLayout.get();
1006
1007 vk::VkShaderCreateInfoEXT vertCreateInfo = vk::makeShaderCreateInfo(
1008 vk::VK_SHADER_STAGE_VERTEX_BIT, vert, tessellationSupported, geometrySupported, &layout);
1009 vk::VkShaderCreateInfoEXT tescCreateInfo = vk::makeShaderCreateInfo(
1010 vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, tesc, tessellationSupported, geometrySupported, &layout);
1011 vk::VkShaderCreateInfoEXT teseCreateInfo = vk::makeShaderCreateInfo(
1012 vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, tese, tessellationSupported, geometrySupported, &layout);
1013 vk::VkShaderCreateInfoEXT geomCreateInfo = vk::makeShaderCreateInfo(
1014 vk::VK_SHADER_STAGE_GEOMETRY_BIT, geom, tessellationSupported, geometrySupported, &layout);
1015 vk::VkShaderCreateInfoEXT fragCreateInfo = vk::makeShaderCreateInfo(
1016 vk::VK_SHADER_STAGE_FRAGMENT_BIT, frag, tessellationSupported, geometrySupported, &layout);
1017
1018 vk::Move<vk::VkShaderEXT> vertShader = vk::createShader(vk, device, vertCreateInfo);
1019 vk::Move<vk::VkShaderEXT> tescShader;
1020 vk::Move<vk::VkShaderEXT> teseShader;
1021 vk::Move<vk::VkShaderEXT> geomShader;
1022 vk::Move<vk::VkShaderEXT> fragShader = vk::createShader(vk, device, fragCreateInfo);
1023
1024 vk::Move<vk::VkShaderModule> vertShaderModule = createShaderModule(vk, device, pipeline_vert);
1025 vk::Move<vk::VkShaderModule> tescShaderModule;
1026 vk::Move<vk::VkShaderModule> teseShaderModule;
1027 vk::Move<vk::VkShaderModule> geomShaderModule;
1028 vk::Move<vk::VkShaderModule> fragShaderModule = createShaderModule(vk, device, pipeline_frag);
1029
1030 if (m_params.tessShader)
1031 {
1032 tescShader = vk::createShader(vk, device, tescCreateInfo);
1033 teseShader = vk::createShader(vk, device, teseCreateInfo);
1034
1035 tescShaderModule = createShaderModule(vk, device, pipeline_tesc);
1036 teseShaderModule = createShaderModule(vk, device, pipeline_tese);
1037 }
1038 if (m_params.geomShader)
1039 {
1040 geomShader = vk::createShader(vk, device, geomCreateInfo);
1041
1042 geomShaderModule = createShaderModule(vk, device, pipeline_geom);
1043 }
1044
1045 const vk::VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
1046 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1047 DE_NULL, // const void* pNext;
1048 0u, // VkPipelineVertexInputStateCreateFlags flags;
1049 0u, // uint32_t vertexBindingDescriptionCount;
1050 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1051 0u, // uint32_t vertexAttributeDescriptionCount;
1052 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1053 };
1054
1055 const vk::VkPipelineTessellationStateCreateInfo tessStateCreateInfo = {
1056 vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
1057 DE_NULL, // const void* pNext;
1058 0u, // VkPipelineTessellationStateCreateFlags flags;
1059 4u, // uint32_t patchControlPoints;
1060 };
1061
1062 const vk::VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo = {
1063 vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1064 DE_NULL, // const void* pNext;
1065 (vk::VkPipelineInputAssemblyStateCreateFlags)0u, // VkPipelineInputAssemblyStateCreateFlags flags;
1066 topology, // VkPrimitiveTopology topology;
1067 VK_FALSE, // VkBool32 primitiveRestartEnable;
1068 };
1069
1070 vk::VkPipelineRenderingCreateInfo pipelineRenderingCreateInfo = {
1071 vk::VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, // VkStructureType sType
1072 DE_NULL, // const void* pNext
1073 0u, // uint32_t viewMask
1074 1u, // uint32_t colorAttachmentCount
1075 &colorAttachmentFormat, // const VkFormat* pColorAttachmentFormats
1076 vk::VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat
1077 vk::VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat
1078 };
1079
1080 const vk::VkViewport viewport =
1081 vk::makeViewport((float)renderArea.extent.width, 0.0f, (float)renderArea.extent.width,
1082 (float)renderArea.extent.height, 0.0f, 1.0f);
1083 const vk::VkRect2D scissor = vk::makeRect2D(renderArea.extent);
1084
1085 const vk::VkPipelineViewportStateCreateInfo viewportStateCreateInfo = {
1086 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType
1087 DE_NULL, // const void* pNext
1088 (vk::VkPipelineViewportStateCreateFlags)0u, // VkPipelineViewportStateCreateFlags flags
1089 1u, // uint32_t viewportCount
1090 &viewport, // const VkViewport* pViewports
1091 1u, // uint32_t scissorCount
1092 &scissor // const VkRect2D* pScissors
1093 };
1094
1095 const auto pipeline = makeGraphicsPipeline(
1096 vk, device, emptyPipelineLayout.get(), vertShaderModule.get(), tescShaderModule.get(), teseShaderModule.get(),
1097 geomShaderModule.get(), fragShaderModule.get(), VK_NULL_HANDLE, 0u, &vertexInputStateParams,
1098 &pipelineInputAssemblyStateInfo, &tessStateCreateInfo, &viewportStateCreateInfo, DE_NULL, DE_NULL, DE_NULL,
1099 DE_NULL, DE_NULL, &pipelineRenderingCreateInfo);
1100
1101 const vk::VkDeviceSize bufferSizeBytes = sizeof(uint32_t) * 4;
1102
1103 const vk::Unique<vk::VkDescriptorSet> descriptorSet(
1104 makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
1105 const vk::BufferWithMemory outputBuffer(
1106 vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
1107 vk::MemoryRequirement::HostVisible);
1108
1109 const vk::VkDescriptorBufferInfo descriptorInfo =
1110 vk::makeDescriptorBufferInfo(*outputBuffer, 0ull, bufferSizeBytes);
1111 vk::DescriptorSetUpdateBuilder()
1112 .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u),
1113 vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
1114 .update(vk, device);
1115
1116 const vk::VkClearValue clearValue = vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 1.0f});
1117 vk::VkImageMemoryBarrier initialBarrier =
1118 vk::makeImageMemoryBarrier(0, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
1119 vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
1120
1121 vk::beginCommandBuffer(vk, *cmdBuffer, 0u);
1122
1123 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1124 vk::VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0, DE_NULL, 0, DE_NULL, 1,
1125 &initialBarrier);
1126
1127 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL,
1128 vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
1129
1130 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1131 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
1132
1133 vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0, 1,
1134 &descriptorSet.get(), 0, DE_NULL);
1135 vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, topology, false,
1136 !m_context.getExtendedDynamicStateFeaturesEXT().extendedDynamicState);
1137
1138 vk::bindGraphicsShaders(vk, *cmdBuffer, (m_params.vertShader) ? *vertShader : VK_NULL_HANDLE,
1139 (m_params.tessShader) ? *tescShader : VK_NULL_HANDLE,
1140 (m_params.tessShader) ? *teseShader : VK_NULL_HANDLE,
1141 (m_params.geomShader) ? *geomShader : VK_NULL_HANDLE,
1142 (m_params.fragShader) ? *fragShader : VK_NULL_HANDLE, taskSupported, meshSupported);
1143
1144 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
1145
1146 vk::endRendering(vk, *cmdBuffer);
1147
1148 vk::endCommandBuffer(vk, *cmdBuffer);
1149
1150 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
1151
1152 if (m_params.fragShader)
1153 {
1154 const vk::VkBufferImageCopy copyRegion = {
1155 0u, // VkDeviceSize bufferOffset;
1156 0u, // uint32_t bufferRowLength;
1157 0u, // uint32_t bufferImageHeight;
1158 {
1159 vk::VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
1160 0u, // uint32_t mipLevel;
1161 0u, // uint32_t baseArrayLayer;
1162 1u, // uint32_t layerCount;
1163 }, // VkImageSubresourceLayers imageSubresource;
1164 {0, 0, 0}, // VkOffset3D imageOffset;
1165 {renderArea.extent.width, renderArea.extent.height, 1} // VkExtent3D imageExtent;
1166 };
1167
1168 vk::beginCommandBuffer(vk, *copyCmdBuffer, 0u);
1169 vk.cmdCopyImageToBuffer(*copyCmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u,
1170 ©Region);
1171 vk::endCommandBuffer(vk, *copyCmdBuffer);
1172 submitCommandsAndWait(vk, device, queue, copyCmdBuffer.get());
1173
1174 if (!verifyImage(colorOutputBuffer))
1175 return tcu::TestStatus::fail("Fail");
1176 }
1177
1178 const vk::Allocation &outputBufferAllocation = outputBuffer.getAllocation();
1179 invalidateAlloc(vk, device, outputBufferAllocation);
1180
1181 const uint32_t *bufferPtr = static_cast<uint32_t *>(outputBufferAllocation.getHostPtr());
1182
1183 if (m_params.vertShader && bufferPtr[0] != 1u)
1184 return tcu::TestStatus::fail("Fail");
1185 if (m_params.tessShader && bufferPtr[1] != 2u)
1186 return tcu::TestStatus::fail("Fail");
1187 if (m_params.geomShader && bufferPtr[2] != 3u)
1188 return tcu::TestStatus::fail("Fail");
1189
1190 return tcu::TestStatus::pass("Pass");
1191 }
1192
verifyImage(de::MovePtr<vk::BufferWithMemory> & outputBuffer)1193 bool ShaderObjectStageBindingInstance::verifyImage(de::MovePtr<vk::BufferWithMemory> &outputBuffer)
1194 {
1195 tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(
1196 vk::mapVkFormat(vk::VK_FORMAT_R8G8B8A8_UNORM), renderArea.extent.width, renderArea.extent.height, 1,
1197 (const void *)outputBuffer->getAllocation().getHostPtr());
1198
1199 const tcu::Vec4 black = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1200 const tcu::Vec4 white = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
1201 const int32_t width = resultBuffer.getWidth();
1202 const int32_t height = resultBuffer.getHeight();
1203
1204 const int32_t xOffset = m_params.tessShader ? 4 : 8;
1205 const int32_t yOffset = m_params.geomShader ? 4 : 8;
1206
1207 for (int32_t j = 0; j < height; ++j)
1208 {
1209 for (int32_t i = 0; i < width; ++i)
1210 {
1211 const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
1212 if (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset)
1213 {
1214 if (color != white)
1215 return false;
1216 }
1217 else
1218 {
1219 if (color != black)
1220 return false;
1221 }
1222 }
1223 }
1224
1225 return true;
1226 }
1227
1228 class ShaderObjectStageBindingCase : public vkt::TestCase
1229 {
1230 public:
ShaderObjectStageBindingCase(tcu::TestContext & testCtx,const std::string & name,const StageTestParams & params)1231 ShaderObjectStageBindingCase(tcu::TestContext &testCtx, const std::string &name, const StageTestParams ¶ms)
1232 : vkt::TestCase(testCtx, name)
1233 , m_params(params)
1234 {
1235 }
~ShaderObjectStageBindingCase(void)1236 virtual ~ShaderObjectStageBindingCase(void)
1237 {
1238 }
1239
1240 void checkSupport(vkt::Context &context) const override;
1241 virtual void initPrograms(vk::SourceCollections &programCollection) const override;
createInstance(Context & context) const1242 TestInstance *createInstance(Context &context) const override
1243 {
1244 return new ShaderObjectStageBindingInstance(context, m_params);
1245 }
1246
1247 private:
1248 StageTestParams m_params;
1249 };
1250
checkSupport(Context & context) const1251 void ShaderObjectStageBindingCase::checkSupport(Context &context) const
1252 {
1253 context.requireDeviceFunctionality("VK_EXT_shader_object");
1254
1255 if (m_params.tessShader)
1256 context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
1257
1258 if (m_params.geomShader)
1259 context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
1260 }
1261
initPrograms(vk::SourceCollections & programCollection) const1262 void ShaderObjectStageBindingCase::initPrograms(vk::SourceCollections &programCollection) const
1263 {
1264 std::stringstream vert;
1265 std::stringstream geom;
1266 std::stringstream tesc;
1267 std::stringstream tese;
1268 std::stringstream frag;
1269
1270 std::stringstream pipeline_vert;
1271 std::stringstream pipeline_geom;
1272 std::stringstream pipeline_tesc;
1273 std::stringstream pipeline_tese;
1274 std::stringstream pipeline_frag;
1275
1276 vert << "#version 450\n"
1277 << "layout(set = 0, binding = 0) buffer Output {\n"
1278 << " uint values[4];\n"
1279 << "} buffer_out;\n\n"
1280 << "void main() {\n"
1281 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
1282 << " gl_Position = vec4(pos - 0.5f, 0.0f, 1.0f);\n"
1283 << " if (gl_VertexIndex == 0u)\n"
1284 << " buffer_out.values[0] = 1u;\n"
1285 << "}\n";
1286
1287 tesc << "#version 450\n"
1288 << "\n"
1289 << "layout(vertices = 4) out;\n"
1290 << "layout(set = 0, binding = 0) buffer Output {\n"
1291 << " uint values[4];\n"
1292 << "} buffer_out;\n\n"
1293 << "\n"
1294 << "void main (void)\n"
1295 << "{\n"
1296 << " if (gl_InvocationID == 0) {\n"
1297 << " gl_TessLevelInner[0] = 1.0;\n"
1298 << " gl_TessLevelInner[1] = 1.0;\n"
1299 << " gl_TessLevelOuter[0] = 1.0;\n"
1300 << " gl_TessLevelOuter[1] = 1.0;\n"
1301 << " gl_TessLevelOuter[2] = 1.0;\n"
1302 << " gl_TessLevelOuter[3] = 1.0;\n"
1303 << " buffer_out.values[1] = 2u;\n"
1304 << " }\n"
1305 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1306 << "}\n";
1307
1308 tese << "#version 450\n"
1309 << "\n"
1310 << "layout(quads, equal_spacing) in;\n"
1311 << "\n"
1312 << "void main (void)\n"
1313 << "{\n"
1314 << " float u = gl_TessCoord.x;\n"
1315 << " float v = gl_TessCoord.y;\n"
1316 << " float omu = 1.0f - u;\n"
1317 << " float omv = 1.0f - v;\n"
1318 << " gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * "
1319 "gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
1320 << " gl_Position.x *= 1.5f;\n"
1321 << "}\n";
1322
1323 geom << "#version 450\n"
1324 << "layout(triangles) in;\n"
1325 << "layout(triangle_strip, max_vertices = 4) out;\n"
1326 << "layout(set = 0, binding = 0) buffer Output {\n"
1327 << " uint values[4];\n"
1328 << "} buffer_out;\n\n"
1329 << "\n"
1330 << "void main(void)\n"
1331 << "{\n"
1332 << " gl_Position = gl_in[0].gl_Position;\n"
1333 << " gl_Position.y *= 1.5f;\n"
1334 << " EmitVertex();\n"
1335 << " gl_Position = gl_in[1].gl_Position;\n"
1336 << " gl_Position.y *= 1.5f;\n"
1337 << " EmitVertex();\n"
1338 << " gl_Position = gl_in[2].gl_Position;\n"
1339 << " gl_Position.y *= 1.5f;\n"
1340 << " EmitVertex();\n"
1341 << " EndPrimitive();\n"
1342 << " if (gl_InvocationID == 0u)\n"
1343 << " buffer_out.values[2] = 3u;\n"
1344 << "}\n";
1345
1346 frag << "#version 450\n"
1347 << "layout (location=0) out vec4 outColor;\n"
1348 << "void main() {\n"
1349 << " outColor = vec4(1.0f);\n"
1350 << "}\n";
1351
1352 pipeline_vert << "#version 450\n"
1353 << "void main() {\n"
1354 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
1355 << " gl_Position = vec4(pos - 0.5f, 0.0f, 1.0f);\n"
1356 << "}\n";
1357
1358 pipeline_tesc << "#version 450\n"
1359 << "\n"
1360 << "layout(vertices = 4) out;\n"
1361 << "\n"
1362 << "void main (void)\n"
1363 << "{\n"
1364 << " if (gl_InvocationID == 0) {\n"
1365 << " gl_TessLevelInner[0] = 1.0;\n"
1366 << " gl_TessLevelInner[1] = 1.0;\n"
1367 << " gl_TessLevelOuter[0] = 1.0;\n"
1368 << " gl_TessLevelOuter[1] = 1.0;\n"
1369 << " gl_TessLevelOuter[2] = 1.0;\n"
1370 << " gl_TessLevelOuter[3] = 1.0;\n"
1371 << " }\n"
1372 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1373 << "}\n";
1374
1375 pipeline_tese << "#version 450\n"
1376 << "\n"
1377 << "layout(quads, equal_spacing) in;\n"
1378 << "\n"
1379 << "void main (void)\n"
1380 << "{\n"
1381 << " float u = gl_TessCoord.x;\n"
1382 << " float v = gl_TessCoord.y;\n"
1383 << " float omu = 1.0f - u;\n"
1384 << " float omv = 1.0f - v;\n"
1385 << " gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * "
1386 "gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
1387 << " gl_Position.x *= 0.5f;\n"
1388 << " gl_Position.y *= 0.5f;\n"
1389 << "}\n";
1390
1391 pipeline_geom << "#version 450\n"
1392 << "layout(triangles) in;\n"
1393 << "layout(triangle_strip, max_vertices = 4) out;\n"
1394 << "\n"
1395 << "void main(void)\n"
1396 << "{\n"
1397 << " gl_Position = gl_in[0].gl_Position;\n"
1398 << " gl_Position.x += 0.25f;\n"
1399 << " gl_Position.y += 0.25f;\n"
1400 << " EmitVertex();\n"
1401 << " gl_Position = gl_in[1].gl_Position;\n"
1402 << " gl_Position.x += 0.25f;\n"
1403 << " gl_Position.y += 0.25f;\n"
1404 << " EmitVertex();\n"
1405 << " gl_Position = gl_in[2].gl_Position;\n"
1406 << " gl_Position.x += 0.25f;\n"
1407 << " gl_Position.y += 0.25f;\n"
1408 << " EmitVertex();\n"
1409 << " EndPrimitive();\n"
1410 << "}\n";
1411
1412 pipeline_frag << "#version 450\n"
1413 << "layout (location=0) out vec4 outColor;\n"
1414 << "void main() {\n"
1415 << " outColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n"
1416 << "}\n";
1417
1418 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
1419 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
1420 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
1421 programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
1422 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
1423
1424 programCollection.glslSources.add("pipeline_vert") << glu::VertexSource(pipeline_vert.str());
1425 programCollection.glslSources.add("pipeline_tesc") << glu::TessellationControlSource(pipeline_tesc.str());
1426 programCollection.glslSources.add("pipeline_tese") << glu::TessellationEvaluationSource(pipeline_tese.str());
1427 programCollection.glslSources.add("pipeline_geom") << glu::GeometrySource(pipeline_geom.str());
1428 programCollection.glslSources.add("pipeline_frag") << glu::FragmentSource(pipeline_frag.str());
1429 }
1430
1431 } // namespace
1432
createShaderObjectPipelineInteractionTests(tcu::TestContext & testCtx)1433 tcu::TestCaseGroup *createShaderObjectPipelineInteractionTests(tcu::TestContext &testCtx)
1434 {
1435 de::MovePtr<tcu::TestCaseGroup> pipelineInteractionGroup(new tcu::TestCaseGroup(testCtx, "pipeline_interaction"));
1436
1437 const struct
1438 {
1439 TestType testType;
1440 const char *name;
1441 } tests[] = {
1442 {SHADER_OBJECT, "shader_object"},
1443 {MAX_PIPELINE, "max_pipeline"},
1444 {MAX_PIPELINE_SHADER_OBJECT_MAX_PIPELINE, "max_pipeline_shader_object_max_pipeline"},
1445 {SHADER_OBJECT_MAX_PIPELINE_SHADER_OBJECT, "shader_object_max_pipeline_shader_object"},
1446 {MIN_PIPELINE_SHADER_OBJECT, "min_pipeline_shader_object"},
1447 {SHADER_OBJECT_MIN_PIPELINE, "shader_object_min_pipeline"},
1448 {RENDER_PASS_PIPELINE_SHADER_OBJECT, "render_pass_pipeline_shader_object"},
1449 {RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN, "render_pass_pipeline_shader_object_after_begin"},
1450 {COMPUTE_SHADER_OBJECT_MIN_PIPELINE, "compute_shader_object_min_pipeline"},
1451 {SHADER_OBJECT_COMPUTE_PIPELINE, "shader_object_compute_pipeline"},
1452 };
1453
1454 for (const auto &test : tests)
1455 {
1456 TestParams params;
1457 params.testType = test.testType;
1458
1459 pipelineInteractionGroup->addChild(new ShaderObjectPipelineInteractionCase(testCtx, test.name, params));
1460 }
1461
1462 const struct
1463 {
1464 StageTestParams shaders;
1465 const char *name;
1466 } shaderBindTests[] = {
1467 {{true, false, false, false}, "vert"}, {{true, true, false, false}, "vert_tess"},
1468 {{true, false, true, false}, "vert_geom"}, {{true, false, false, true}, "vert_frag"},
1469 {{true, true, true, false}, "vert_tess_geom"}, {{true, true, false, true}, "vert_tess_frag"},
1470 {{true, false, true, true}, "vert_geom_frag"}, {{true, true, true, true}, "vert_tess_geom_frag"},
1471 };
1472
1473 for (const auto &shaderBindTest : shaderBindTests)
1474 {
1475 pipelineInteractionGroup->addChild(
1476 new ShaderObjectStageBindingCase(testCtx, shaderBindTest.name, shaderBindTest.shaders));
1477 }
1478
1479 return pipelineInteractionGroup.release();
1480 }
1481
1482 } // namespace ShaderObject
1483 } // namespace vkt
1484