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.getMeshShaderFeaturesEXT().taskShader;
147 const bool meshSupported = m_context.getMeshShaderFeaturesEXT().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_NV_scissor_exclusive"))
471 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_ENABLE_NV);
472 if (extensionEnabled(deviceExtensions, "VK_EXT_discard_rectangles"))
473 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT);
474 if (extensionEnabled(deviceExtensions, "VK_EXT_discard_rectangles"))
475 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT);
476 if (extensionEnabled(deviceExtensions, "VK_EXT_discard_rectangles"))
477 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT);
478 if (extensionEnabled(deviceExtensions, "VK_EXT_attachment_feedback_loop_dynamic_state"))
479 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT);
480
481 const vk::VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = {
482 vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
483 DE_NULL, // const void* pNext;
484 (vk::VkPipelineDynamicStateCreateFlags)0u, // VkPipelineDynamicStateCreateFlags flags;
485 static_cast<uint32_t>(dynamicStates.size()), // uint32_t dynamicStateCount;
486 dynamicStates.data(), // const VkDynamicState* pDynamicStates;
487 };
488 const vk::VkPipelineDynamicStateCreateInfo *pipelineDynamicState =
489 (createDynamicPipeline) ? &dynamicStateCreateInfo : DE_NULL;
490
491 const vk::VkDeviceSize bufferSizeBytes = sizeof(uint32_t) * 4;
492
493 const vk::Unique<vk::VkDescriptorSet> descriptorSet(
494 makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
495 const vk::BufferWithMemory outputBuffer(
496 vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
497 vk::MemoryRequirement::HostVisible);
498
499 const vk::VkDescriptorBufferInfo descriptorInfo =
500 vk::makeDescriptorBufferInfo(*outputBuffer, 0ull, bufferSizeBytes);
501 vk::DescriptorSetUpdateBuilder()
502 .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u),
503 vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
504 .update(vk, device);
505
506 vk::VkPipelineRenderingCreateInfo *pPipelineRenderingCreateInfo = &pipelineRenderingCreateInfo;
507 vk::VkRenderPass renderPassHandle = VK_NULL_HANDLE;
508 if (m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT ||
509 m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN)
510 {
511 pPipelineRenderingCreateInfo = DE_NULL;
512 renderPassHandle = *renderPass;
513 }
514
515 const auto pipeline1 = makeGraphicsPipeline(
516 vk, device, pipelineLayout.get(), vertShaderModule1.get(), tescShaderModule.get(), teseShaderModule.get(),
517 geomShaderModule.get(), fragShaderModule1.get(), renderPassHandle, 0u, &vertexInputStateParams,
518 &pipelineInputAssemblyStateInfo, &tessStateCreateInfo, &viewportStateCreateInfo, DE_NULL, DE_NULL, DE_NULL,
519 DE_NULL, pipelineDynamicState, pPipelineRenderingCreateInfo);
520 const auto pipeline2 = makeGraphicsPipeline(
521 vk, device, pipelineLayout.get(), vertShaderModule2.get(), tescShaderModule.get(), teseShaderModule.get(),
522 geomShaderModule.get(), fragShaderModule2.get(), renderPassHandle, 0u, &vertexInputStateParams,
523 &pipelineInputAssemblyStateInfo, &tessStateCreateInfo, &viewportStateCreateInfo, DE_NULL, DE_NULL, DE_NULL,
524 DE_NULL, pipelineDynamicState, pPipelineRenderingCreateInfo);
525 const auto pipeline3 = makeGraphicsPipeline(
526 vk, device, pipelineLayout.get(), vertShaderModule3.get(), tescShaderModule.get(), teseShaderModule.get(),
527 geomShaderModule.get(), fragShaderModule3.get(), renderPassHandle, 0u, &vertexInputStateParams,
528 &pipelineInputAssemblyStateInfo, &tessStateCreateInfo, &viewportStateCreateInfo, DE_NULL, DE_NULL, DE_NULL,
529 DE_NULL, pipelineDynamicState, pPipelineRenderingCreateInfo);
530 const auto computePipeline =
531 vk::makeComputePipeline(vk, device, computePipelineLayout.get(), compShaderModule.get());
532
533 const vk::VkClearValue clearValue = vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 1.0f});
534 vk::VkImageMemoryBarrier initialBarrier =
535 vk::makeImageMemoryBarrier(0, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
536 vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
537
538 const vk::VkDeviceSize bufferSize = 64;
539 de::MovePtr<vk::BufferWithMemory> buffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
540 vk, device, alloc, vk::makeBufferCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
541 vk::MemoryRequirement::HostVisible));
542
543 vk::beginCommandBuffer(vk, *cmdBuffer, 0u);
544
545 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
546 vk::VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0, DE_NULL, 0, DE_NULL, 1,
547 &initialBarrier);
548
549 if (m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT)
550 {
551 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
552 }
553
554 if (m_params.testType != COMPUTE_SHADER_OBJECT_MIN_PIPELINE && m_params.testType != SHADER_OBJECT_COMPUTE_PIPELINE)
555 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL,
556 vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
557
558 vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,
559 false,
560 !m_context.getExtendedDynamicStateFeaturesEXT().extendedDynamicState);
561 vk::bindNullTaskMeshShaders(vk, *cmdBuffer, m_context.getMeshShaderFeaturesEXT());
562
563 vk::VkDeviceSize offset = 0u;
564 vk::VkDeviceSize stride = 16u;
565 vk.cmdBindVertexBuffers2(*cmdBuffer, 0u, 1u, &**buffer, &offset, &bufferSize, &stride);
566
567 if (m_params.testType == SHADER_OBJECT)
568 {
569 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1,
570 taskSupported, meshSupported);
571 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
572 }
573 else if (m_params.testType == MAX_PIPELINE)
574 {
575 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
576 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
577 }
578 else if (m_params.testType == MAX_PIPELINE_SHADER_OBJECT_MAX_PIPELINE)
579 {
580 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
581 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
582
583 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader2, *tescShader, *teseShader, *geomShader, *fragShader2,
584 taskSupported, meshSupported);
585 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
586
587 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline3);
588 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
589 }
590 else if (m_params.testType == SHADER_OBJECT_MAX_PIPELINE_SHADER_OBJECT)
591 {
592 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1,
593 taskSupported, meshSupported);
594 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
595
596 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline2);
597 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
598
599 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader3, *tescShader, *teseShader, *geomShader, *fragShader3,
600 taskSupported, meshSupported);
601 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
602 }
603 else if (m_params.testType == MIN_PIPELINE_SHADER_OBJECT)
604 {
605 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
606 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
607
608 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader2, *tescShader, *teseShader, *geomShader, *fragShader2,
609 taskSupported, meshSupported);
610 vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,
611 false,
612 !m_context.getExtendedDynamicStateFeaturesEXT().extendedDynamicState);
613 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
614 }
615 else if (m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT)
616 {
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 == RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN)
622 {
623 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
624 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1,
625 taskSupported, meshSupported);
626 vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,
627 false,
628 !m_context.getExtendedDynamicStateFeaturesEXT().extendedDynamicState);
629 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
630 }
631 else if (m_params.testType == SHADER_OBJECT_MIN_PIPELINE)
632 {
633 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1,
634 taskSupported, meshSupported);
635 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
636
637 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline2);
638 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
639 }
640 else if (m_params.testType == COMPUTE_SHADER_OBJECT_MIN_PIPELINE)
641 {
642 vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, computePipelineLayout.get(), 0, 1,
643 &descriptorSet.get(), 0, DE_NULL);
644
645 vk::VkShaderStageFlagBits stages[] = {vk::VK_SHADER_STAGE_COMPUTE_BIT};
646 vk.cmdBindShadersEXT(*cmdBuffer, 1, stages, &*compShader);
647 vk.cmdDispatch(*cmdBuffer, 4, 1, 1);
648
649 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL,
650 vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
651 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
652 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
653 vk::endRendering(vk, *cmdBuffer);
654 }
655 else if (m_params.testType == SHADER_OBJECT_COMPUTE_PIPELINE)
656 {
657 vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, computePipelineLayout.get(), 0, 1,
658 &descriptorSet.get(), 0, DE_NULL);
659
660 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL,
661 vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
662 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1,
663 taskSupported, meshSupported);
664 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
665 vk::endRendering(vk, *cmdBuffer);
666
667 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
668 vk.cmdDispatch(*cmdBuffer, 4, 1, 1);
669 }
670
671 if (m_params.testType != COMPUTE_SHADER_OBJECT_MIN_PIPELINE && m_params.testType != SHADER_OBJECT_COMPUTE_PIPELINE)
672 vk::endRendering(vk, *cmdBuffer);
673
674 vk::endCommandBuffer(vk, *cmdBuffer);
675
676 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
677
678 const vk::VkBufferImageCopy copyRegion = {
679 0u, // VkDeviceSize bufferOffset;
680 0u, // uint32_t bufferRowLength;
681 0u, // uint32_t bufferImageHeight;
682 {
683 vk::VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
684 0u, // uint32_t mipLevel;
685 0u, // uint32_t baseArrayLayer;
686 1u, // uint32_t layerCount;
687 }, // VkImageSubresourceLayers imageSubresource;
688 {0, 0, 0}, // VkOffset3D imageOffset;
689 {renderArea.extent.width, renderArea.extent.height, 1} // VkExtent3D imageExtent;
690 };
691
692 vk::beginCommandBuffer(vk, *copyCmdBuffer, 0u);
693 vk.cmdCopyImageToBuffer(*copyCmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u, ©Region);
694 vk::endCommandBuffer(vk, *copyCmdBuffer);
695 submitCommandsAndWait(vk, device, queue, copyCmdBuffer.get());
696
697 if (!verifyImage(colorOutputBuffer, getDrawCount()))
698 return tcu::TestStatus::fail("Fail");
699
700 if (m_params.testType == COMPUTE_SHADER_OBJECT_MIN_PIPELINE || m_params.testType == SHADER_OBJECT_COMPUTE_PIPELINE)
701 {
702 const vk::Allocation &outputBufferAllocation = outputBuffer.getAllocation();
703 invalidateAlloc(vk, device, outputBufferAllocation);
704
705 const uint32_t *bufferPtr = static_cast<uint32_t *>(outputBufferAllocation.getHostPtr());
706
707 for (uint32_t i = 0; i < 4; ++i)
708 {
709 if (bufferPtr[i] != i)
710 return tcu::TestStatus::fail("Fail");
711 }
712 }
713
714 return tcu::TestStatus::pass("Pass");
715 }
716
verifyImage(de::MovePtr<vk::BufferWithMemory> & outputBuffer,uint32_t drawCount)717 bool ShaderObjectPipelineInteractionInstance::verifyImage(de::MovePtr<vk::BufferWithMemory> &outputBuffer,
718 uint32_t drawCount)
719 {
720 tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(
721 vk::mapVkFormat(vk::VK_FORMAT_R8G8B8A8_UNORM), renderArea.extent.width, renderArea.extent.height, 1,
722 (const void *)outputBuffer->getAllocation().getHostPtr());
723
724 const tcu::Vec4 red = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
725 const tcu::Vec4 green = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
726 const tcu::Vec4 blue = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
727 const int32_t width = resultBuffer.getWidth();
728 const int32_t height = resultBuffer.getHeight();
729
730 for (int32_t j = 0; j < height; ++j)
731 {
732 for (int32_t i = 0; i < width; ++i)
733 {
734 const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
735 if (i < width / 2 && j < height / 2 && drawCount > 0)
736 {
737 if (color != red)
738 return false;
739 }
740 else if (i >= width / 2 && j < height / 2 && drawCount > 1)
741 {
742 if (color != green)
743 return false;
744 }
745 else if (i < width / 2 && j >= height / 2 && drawCount > 2)
746 {
747 if (color != blue)
748 return false;
749 }
750 }
751 }
752
753 return true;
754 }
755
756 class ShaderObjectPipelineInteractionCase : public vkt::TestCase
757 {
758 public:
ShaderObjectPipelineInteractionCase(tcu::TestContext & testCtx,const std::string & name,const TestParams & params)759 ShaderObjectPipelineInteractionCase(tcu::TestContext &testCtx, const std::string &name, const TestParams ¶ms)
760 : vkt::TestCase(testCtx, name)
761 , m_params(params)
762 {
763 }
~ShaderObjectPipelineInteractionCase(void)764 virtual ~ShaderObjectPipelineInteractionCase(void)
765 {
766 }
767
768 void checkSupport(vkt::Context &context) const override;
769 virtual void initPrograms(vk::SourceCollections &programCollection) const override;
createInstance(Context & context) const770 TestInstance *createInstance(Context &context) const override
771 {
772 return new ShaderObjectPipelineInteractionInstance(context, m_params);
773 }
774
775 private:
776 TestParams m_params;
777 };
778
initPrograms(vk::SourceCollections & programCollection) const779 void ShaderObjectPipelineInteractionCase::initPrograms(vk::SourceCollections &programCollection) const
780 {
781 std::stringstream vert1, vert2, vert3;
782 std::stringstream geom;
783 std::stringstream tesc;
784 std::stringstream tese;
785 std::stringstream frag1, frag2, frag3;
786 std::stringstream comp;
787
788 vert1 << "#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.5f), 0.0f, 1.0f);\n"
792 << "}\n";
793 vert2 << "#version 450\n"
794 << "void main() {\n"
795 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
796 << " gl_Position = vec4(pos * 0.5f - vec2(0.0f, 0.5f), 0.0f, 1.0f);\n"
797 << "}\n";
798 vert3 << "#version 450\n"
799 << "void main() {\n"
800 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
801 << " gl_Position = vec4(pos * 0.5f - vec2(0.5f, 0.0f), 0.0f, 1.0f);\n"
802 << "}\n";
803
804 tesc << "#version 450\n"
805 << "\n"
806 << "layout(vertices = 4) out;\n"
807 << "\n"
808 << "void main (void)\n"
809 << "{\n"
810 << " if (gl_InvocationID == 0) {\n"
811 << " gl_TessLevelInner[0] = 1.0;\n"
812 << " gl_TessLevelInner[1] = 1.0;\n"
813 << " gl_TessLevelOuter[0] = 1.0;\n"
814 << " gl_TessLevelOuter[1] = 1.0;\n"
815 << " gl_TessLevelOuter[2] = 1.0;\n"
816 << " gl_TessLevelOuter[3] = 1.0;\n"
817 << " }\n"
818 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
819 << "}\n";
820
821 tese << "#version 450\n"
822 << "\n"
823 << "layout(quads, equal_spacing) in;\n"
824 << "\n"
825 << "void main (void)\n"
826 << "{\n"
827 << " float u = gl_TessCoord.x;\n"
828 << " float v = gl_TessCoord.y;\n"
829 << " float omu = 1.0f - u;\n"
830 << " float omv = 1.0f - v;\n"
831 << " gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * "
832 "gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
833 << " gl_Position.x *= 2.0f;\n"
834 << "}\n";
835
836 geom << "#version 450\n"
837 << "layout(triangles) in;\n"
838 << "layout(triangle_strip, max_vertices = 4) out;\n"
839 << "\n"
840 << "void main(void)\n"
841 << "{\n"
842 << " gl_Position = gl_in[0].gl_Position;\n"
843 << " gl_Position.y *= 2.0f;\n"
844 << " EmitVertex();\n"
845 << " gl_Position = gl_in[1].gl_Position;\n"
846 << " gl_Position.y *= 2.0f;\n"
847 << " EmitVertex();\n"
848 << " gl_Position = gl_in[2].gl_Position;\n"
849 << " gl_Position.y *= 2.0f;\n"
850 << " EmitVertex();\n"
851 << " EndPrimitive();\n"
852 << "}\n";
853
854 frag1 << "#version 450\n"
855 << "layout (location=0) out vec4 outColor;\n"
856 << "void main() {\n"
857 << " outColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n"
858 << "}\n";
859 frag2 << "#version 450\n"
860 << "layout (location=0) out vec4 outColor;\n"
861 << "void main() {\n"
862 << " outColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n"
863 << "}\n";
864 frag3 << "#version 450\n"
865 << "layout (location=0) out vec4 outColor;\n"
866 << "void main() {\n"
867 << " outColor = vec4(0.0f, 0.0f, 1.0f, 1.0f);\n"
868 << "}\n";
869
870 comp << "#version 450\n"
871 << "layout(local_size_x=16, local_size_x=1, local_size_x=1) in;\n"
872 << "layout(binding = 0) buffer Output {\n"
873 << " uint values[16];\n"
874 << "} buffer_out;\n\n"
875 << "void main() {\n"
876 << " buffer_out.values[gl_LocalInvocationID.x] = gl_LocalInvocationID.x;\n"
877 << "}\n";
878
879 programCollection.glslSources.add("vert1") << glu::VertexSource(vert1.str());
880 programCollection.glslSources.add("vert2") << glu::VertexSource(vert2.str());
881 programCollection.glslSources.add("vert3") << glu::VertexSource(vert3.str());
882 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
883 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
884 programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
885 programCollection.glslSources.add("frag1") << glu::FragmentSource(frag1.str());
886 programCollection.glslSources.add("frag2") << glu::FragmentSource(frag2.str());
887 programCollection.glslSources.add("frag3") << glu::FragmentSource(frag3.str());
888 programCollection.glslSources.add("comp") << glu::ComputeSource(comp.str());
889 }
890
checkSupport(Context & context) const891 void ShaderObjectPipelineInteractionCase::checkSupport(Context &context) const
892 {
893 context.requireDeviceFunctionality("VK_EXT_shader_object");
894
895 context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
896 context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
897 }
898
899 class ShaderObjectStageBindingInstance : public vkt::TestInstance
900 {
901 public:
ShaderObjectStageBindingInstance(Context & context,const StageTestParams & params)902 ShaderObjectStageBindingInstance(Context &context, const StageTestParams ¶ms)
903 : vkt::TestInstance(context)
904 , m_params(params)
905 {
906 }
~ShaderObjectStageBindingInstance(void)907 virtual ~ShaderObjectStageBindingInstance(void)
908 {
909 }
910
911 tcu::TestStatus iterate(void) override;
912
913 private:
914 bool verifyImage(de::MovePtr<vk::BufferWithMemory> &outputBuffer);
915 StageTestParams m_params;
916
917 const vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
918 const vk::VkRect2D renderArea = {{
919 0u,
920 0u,
921 },
922 {
923 32u,
924 32u,
925 }};
926 };
927
iterate(void)928 tcu::TestStatus ShaderObjectStageBindingInstance::iterate(void)
929 {
930 const vk::DeviceInterface &vk = m_context.getDeviceInterface();
931 const vk::VkDevice device = m_context.getDevice();
932 const vk::VkQueue queue = m_context.getUniversalQueue();
933 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
934 auto &alloc = m_context.getDefaultAllocator();
935 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(
936 m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
937 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
938 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader;
939 const bool taskSupported = m_context.getMeshShaderFeaturesEXT().taskShader;
940 const bool meshSupported = m_context.getMeshShaderFeaturesEXT().meshShader;
941
942 const auto subresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
943
944 const vk::VkImageCreateInfo createInfo = {
945 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
946 DE_NULL, // const void* pNext
947 0u, // VkImageCreateFlags flags
948 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
949 colorAttachmentFormat, // VkFormat format
950 {renderArea.extent.width, renderArea.extent.height, 1}, // VkExtent3D extent
951 1u, // uint32_t mipLevels
952 1u, // uint32_t arrayLayers
953 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
954 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
955 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage
956 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
957 0, // uint32_t queueFamilyIndexCount
958 DE_NULL, // const uint32_t* pQueueFamilyIndices
959 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
960 };
961
962 de::MovePtr<vk::ImageWithMemory> image = de::MovePtr<vk::ImageWithMemory>(
963 new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
964 const auto imageView =
965 vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
966
967 const vk::VkDeviceSize colorOutputBufferSize =
968 renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
969 de::MovePtr<vk::BufferWithMemory> colorOutputBuffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
970 vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT),
971 vk::MemoryRequirement::HostVisible));
972
973 const vk::VkCommandPoolCreateInfo cmdPoolInfo = {
974 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType
975 DE_NULL, // pNext
976 vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags
977 queueFamilyIndex, // queuefamilyindex
978 };
979
980 const vk::Move<vk::VkCommandPool> cmdPool(createCommandPool(vk, device, &cmdPoolInfo));
981 const vk::Move<vk::VkCommandBuffer> cmdBuffer(
982 allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
983 const vk::Move<vk::VkCommandBuffer> copyCmdBuffer(
984 allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
985
986 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
987 vk::DescriptorSetLayoutBuilder()
988 .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_ALL_GRAPHICS)
989 .build(vk, device));
990
991 const vk::Unique<vk::VkDescriptorPool> descriptorPool(
992 vk::DescriptorPoolBuilder()
993 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
994 .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
995
996 const auto topology =
997 m_params.tessShader ? vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
998
999 const auto pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout.get());
1000 const auto emptyPipelineLayout = makePipelineLayout(vk, device);
1001
1002 const auto &binaries = m_context.getBinaryCollection();
1003 const auto &vert = binaries.get("vert");
1004 const auto &tesc = binaries.get("tesc");
1005 const auto &tese = binaries.get("tese");
1006 const auto &geom = binaries.get("geom");
1007 const auto &frag = binaries.get("frag");
1008
1009 const auto &pipeline_vert = binaries.get("pipeline_vert");
1010 const auto &pipeline_tesc = binaries.get("pipeline_tesc");
1011 const auto &pipeline_tese = binaries.get("pipeline_tese");
1012 const auto &pipeline_geom = binaries.get("pipeline_geom");
1013 const auto &pipeline_frag = binaries.get("pipeline_frag");
1014
1015 vk::VkDescriptorSetLayout layout = descriptorSetLayout.get();
1016
1017 vk::VkShaderCreateInfoEXT vertCreateInfo = vk::makeShaderCreateInfo(
1018 vk::VK_SHADER_STAGE_VERTEX_BIT, vert, tessellationSupported, geometrySupported, &layout);
1019 vk::VkShaderCreateInfoEXT tescCreateInfo = vk::makeShaderCreateInfo(
1020 vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, tesc, tessellationSupported, geometrySupported, &layout);
1021 vk::VkShaderCreateInfoEXT teseCreateInfo = vk::makeShaderCreateInfo(
1022 vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, tese, tessellationSupported, geometrySupported, &layout);
1023 vk::VkShaderCreateInfoEXT geomCreateInfo = vk::makeShaderCreateInfo(
1024 vk::VK_SHADER_STAGE_GEOMETRY_BIT, geom, tessellationSupported, geometrySupported, &layout);
1025 vk::VkShaderCreateInfoEXT fragCreateInfo = vk::makeShaderCreateInfo(
1026 vk::VK_SHADER_STAGE_FRAGMENT_BIT, frag, tessellationSupported, geometrySupported, &layout);
1027
1028 vk::Move<vk::VkShaderEXT> vertShader = vk::createShader(vk, device, vertCreateInfo);
1029 vk::Move<vk::VkShaderEXT> tescShader;
1030 vk::Move<vk::VkShaderEXT> teseShader;
1031 vk::Move<vk::VkShaderEXT> geomShader;
1032 vk::Move<vk::VkShaderEXT> fragShader = vk::createShader(vk, device, fragCreateInfo);
1033
1034 vk::Move<vk::VkShaderModule> vertShaderModule = createShaderModule(vk, device, pipeline_vert);
1035 vk::Move<vk::VkShaderModule> tescShaderModule;
1036 vk::Move<vk::VkShaderModule> teseShaderModule;
1037 vk::Move<vk::VkShaderModule> geomShaderModule;
1038 vk::Move<vk::VkShaderModule> fragShaderModule = createShaderModule(vk, device, pipeline_frag);
1039
1040 if (m_params.tessShader)
1041 {
1042 tescShader = vk::createShader(vk, device, tescCreateInfo);
1043 teseShader = vk::createShader(vk, device, teseCreateInfo);
1044
1045 tescShaderModule = createShaderModule(vk, device, pipeline_tesc);
1046 teseShaderModule = createShaderModule(vk, device, pipeline_tese);
1047 }
1048 if (m_params.geomShader)
1049 {
1050 geomShader = vk::createShader(vk, device, geomCreateInfo);
1051
1052 geomShaderModule = createShaderModule(vk, device, pipeline_geom);
1053 }
1054
1055 const vk::VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
1056 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1057 DE_NULL, // const void* pNext;
1058 0u, // VkPipelineVertexInputStateCreateFlags flags;
1059 0u, // uint32_t vertexBindingDescriptionCount;
1060 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1061 0u, // uint32_t vertexAttributeDescriptionCount;
1062 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1063 };
1064
1065 const vk::VkPipelineTessellationStateCreateInfo tessStateCreateInfo = {
1066 vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
1067 DE_NULL, // const void* pNext;
1068 0u, // VkPipelineTessellationStateCreateFlags flags;
1069 4u, // uint32_t patchControlPoints;
1070 };
1071
1072 const vk::VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo = {
1073 vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1074 DE_NULL, // const void* pNext;
1075 (vk::VkPipelineInputAssemblyStateCreateFlags)0u, // VkPipelineInputAssemblyStateCreateFlags flags;
1076 topology, // VkPrimitiveTopology topology;
1077 VK_FALSE, // VkBool32 primitiveRestartEnable;
1078 };
1079
1080 vk::VkPipelineRenderingCreateInfo pipelineRenderingCreateInfo = {
1081 vk::VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, // VkStructureType sType
1082 DE_NULL, // const void* pNext
1083 0u, // uint32_t viewMask
1084 1u, // uint32_t colorAttachmentCount
1085 &colorAttachmentFormat, // const VkFormat* pColorAttachmentFormats
1086 vk::VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat
1087 vk::VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat
1088 };
1089
1090 const vk::VkViewport viewport =
1091 vk::makeViewport((float)renderArea.extent.width, 0.0f, (float)renderArea.extent.width,
1092 (float)renderArea.extent.height, 0.0f, 1.0f);
1093 const vk::VkRect2D scissor = vk::makeRect2D(renderArea.extent);
1094
1095 const vk::VkPipelineViewportStateCreateInfo viewportStateCreateInfo = {
1096 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType
1097 DE_NULL, // const void* pNext
1098 (vk::VkPipelineViewportStateCreateFlags)0u, // VkPipelineViewportStateCreateFlags flags
1099 1u, // uint32_t viewportCount
1100 &viewport, // const VkViewport* pViewports
1101 1u, // uint32_t scissorCount
1102 &scissor // const VkRect2D* pScissors
1103 };
1104
1105 const auto pipeline = makeGraphicsPipeline(
1106 vk, device, emptyPipelineLayout.get(), vertShaderModule.get(), tescShaderModule.get(), teseShaderModule.get(),
1107 geomShaderModule.get(), fragShaderModule.get(), VK_NULL_HANDLE, 0u, &vertexInputStateParams,
1108 &pipelineInputAssemblyStateInfo, &tessStateCreateInfo, &viewportStateCreateInfo, DE_NULL, DE_NULL, DE_NULL,
1109 DE_NULL, DE_NULL, &pipelineRenderingCreateInfo);
1110
1111 const vk::VkDeviceSize bufferSizeBytes = sizeof(uint32_t) * 4;
1112
1113 const vk::Unique<vk::VkDescriptorSet> descriptorSet(
1114 makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
1115 const vk::BufferWithMemory outputBuffer(
1116 vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
1117 vk::MemoryRequirement::HostVisible);
1118
1119 const vk::VkDescriptorBufferInfo descriptorInfo =
1120 vk::makeDescriptorBufferInfo(*outputBuffer, 0ull, bufferSizeBytes);
1121 vk::DescriptorSetUpdateBuilder()
1122 .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u),
1123 vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
1124 .update(vk, device);
1125
1126 const vk::VkClearValue clearValue = vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 1.0f});
1127 vk::VkImageMemoryBarrier initialBarrier =
1128 vk::makeImageMemoryBarrier(0, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
1129 vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
1130
1131 vk::beginCommandBuffer(vk, *cmdBuffer, 0u);
1132
1133 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1134 vk::VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0, DE_NULL, 0, DE_NULL, 1,
1135 &initialBarrier);
1136
1137 vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL,
1138 vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
1139
1140 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1141 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
1142
1143 vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0, 1,
1144 &descriptorSet.get(), 0, DE_NULL);
1145 vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, topology, false,
1146 !m_context.getExtendedDynamicStateFeaturesEXT().extendedDynamicState);
1147
1148 vk::bindGraphicsShaders(vk, *cmdBuffer, (m_params.vertShader) ? *vertShader : VK_NULL_HANDLE,
1149 (m_params.tessShader) ? *tescShader : VK_NULL_HANDLE,
1150 (m_params.tessShader) ? *teseShader : VK_NULL_HANDLE,
1151 (m_params.geomShader) ? *geomShader : VK_NULL_HANDLE,
1152 (m_params.fragShader) ? *fragShader : VK_NULL_HANDLE, taskSupported, meshSupported);
1153
1154 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
1155
1156 vk::endRendering(vk, *cmdBuffer);
1157
1158 vk::endCommandBuffer(vk, *cmdBuffer);
1159
1160 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
1161
1162 if (m_params.fragShader)
1163 {
1164 const vk::VkBufferImageCopy copyRegion = {
1165 0u, // VkDeviceSize bufferOffset;
1166 0u, // uint32_t bufferRowLength;
1167 0u, // uint32_t bufferImageHeight;
1168 {
1169 vk::VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
1170 0u, // uint32_t mipLevel;
1171 0u, // uint32_t baseArrayLayer;
1172 1u, // uint32_t layerCount;
1173 }, // VkImageSubresourceLayers imageSubresource;
1174 {0, 0, 0}, // VkOffset3D imageOffset;
1175 {renderArea.extent.width, renderArea.extent.height, 1} // VkExtent3D imageExtent;
1176 };
1177
1178 vk::beginCommandBuffer(vk, *copyCmdBuffer, 0u);
1179 vk.cmdCopyImageToBuffer(*copyCmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u,
1180 ©Region);
1181 vk::endCommandBuffer(vk, *copyCmdBuffer);
1182 submitCommandsAndWait(vk, device, queue, copyCmdBuffer.get());
1183
1184 if (!verifyImage(colorOutputBuffer))
1185 return tcu::TestStatus::fail("Fail");
1186 }
1187
1188 const vk::Allocation &outputBufferAllocation = outputBuffer.getAllocation();
1189 invalidateAlloc(vk, device, outputBufferAllocation);
1190
1191 const uint32_t *bufferPtr = static_cast<uint32_t *>(outputBufferAllocation.getHostPtr());
1192
1193 if (m_params.vertShader && bufferPtr[0] != 1u)
1194 return tcu::TestStatus::fail("Fail");
1195 if (m_params.tessShader && bufferPtr[1] != 2u)
1196 return tcu::TestStatus::fail("Fail");
1197 if (m_params.geomShader && bufferPtr[2] != 3u)
1198 return tcu::TestStatus::fail("Fail");
1199
1200 return tcu::TestStatus::pass("Pass");
1201 }
1202
verifyImage(de::MovePtr<vk::BufferWithMemory> & outputBuffer)1203 bool ShaderObjectStageBindingInstance::verifyImage(de::MovePtr<vk::BufferWithMemory> &outputBuffer)
1204 {
1205 tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(
1206 vk::mapVkFormat(vk::VK_FORMAT_R8G8B8A8_UNORM), renderArea.extent.width, renderArea.extent.height, 1,
1207 (const void *)outputBuffer->getAllocation().getHostPtr());
1208
1209 const tcu::Vec4 black = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1210 const tcu::Vec4 white = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
1211 const int32_t width = resultBuffer.getWidth();
1212 const int32_t height = resultBuffer.getHeight();
1213
1214 const int32_t xOffset = m_params.tessShader ? 4 : 8;
1215 const int32_t yOffset = m_params.geomShader ? 4 : 8;
1216
1217 for (int32_t j = 0; j < height; ++j)
1218 {
1219 for (int32_t i = 0; i < width; ++i)
1220 {
1221 const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
1222 if (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset)
1223 {
1224 if (color != white)
1225 return false;
1226 }
1227 else
1228 {
1229 if (color != black)
1230 return false;
1231 }
1232 }
1233 }
1234
1235 return true;
1236 }
1237
1238 class ShaderObjectStageBindingCase : public vkt::TestCase
1239 {
1240 public:
ShaderObjectStageBindingCase(tcu::TestContext & testCtx,const std::string & name,const StageTestParams & params)1241 ShaderObjectStageBindingCase(tcu::TestContext &testCtx, const std::string &name, const StageTestParams ¶ms)
1242 : vkt::TestCase(testCtx, name)
1243 , m_params(params)
1244 {
1245 }
~ShaderObjectStageBindingCase(void)1246 virtual ~ShaderObjectStageBindingCase(void)
1247 {
1248 }
1249
1250 void checkSupport(vkt::Context &context) const override;
1251 virtual void initPrograms(vk::SourceCollections &programCollection) const override;
createInstance(Context & context) const1252 TestInstance *createInstance(Context &context) const override
1253 {
1254 return new ShaderObjectStageBindingInstance(context, m_params);
1255 }
1256
1257 private:
1258 StageTestParams m_params;
1259 };
1260
checkSupport(Context & context) const1261 void ShaderObjectStageBindingCase::checkSupport(Context &context) const
1262 {
1263 context.requireDeviceFunctionality("VK_EXT_shader_object");
1264
1265 if (m_params.tessShader)
1266 context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
1267
1268 if (m_params.geomShader)
1269 context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
1270 }
1271
initPrograms(vk::SourceCollections & programCollection) const1272 void ShaderObjectStageBindingCase::initPrograms(vk::SourceCollections &programCollection) const
1273 {
1274 std::stringstream vert;
1275 std::stringstream geom;
1276 std::stringstream tesc;
1277 std::stringstream tese;
1278 std::stringstream frag;
1279
1280 std::stringstream pipeline_vert;
1281 std::stringstream pipeline_geom;
1282 std::stringstream pipeline_tesc;
1283 std::stringstream pipeline_tese;
1284 std::stringstream pipeline_frag;
1285
1286 vert << "#version 450\n"
1287 << "layout(set = 0, binding = 0) buffer Output {\n"
1288 << " uint values[4];\n"
1289 << "} buffer_out;\n\n"
1290 << "void main() {\n"
1291 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
1292 << " gl_Position = vec4(pos - 0.5f, 0.0f, 1.0f);\n"
1293 << " if (gl_VertexIndex == 0u)\n"
1294 << " buffer_out.values[0] = 1u;\n"
1295 << "}\n";
1296
1297 tesc << "#version 450\n"
1298 << "\n"
1299 << "layout(vertices = 4) out;\n"
1300 << "layout(set = 0, binding = 0) buffer Output {\n"
1301 << " uint values[4];\n"
1302 << "} buffer_out;\n\n"
1303 << "\n"
1304 << "void main (void)\n"
1305 << "{\n"
1306 << " if (gl_InvocationID == 0) {\n"
1307 << " gl_TessLevelInner[0] = 1.0;\n"
1308 << " gl_TessLevelInner[1] = 1.0;\n"
1309 << " gl_TessLevelOuter[0] = 1.0;\n"
1310 << " gl_TessLevelOuter[1] = 1.0;\n"
1311 << " gl_TessLevelOuter[2] = 1.0;\n"
1312 << " gl_TessLevelOuter[3] = 1.0;\n"
1313 << " buffer_out.values[1] = 2u;\n"
1314 << " }\n"
1315 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1316 << "}\n";
1317
1318 tese << "#version 450\n"
1319 << "\n"
1320 << "layout(quads, equal_spacing) in;\n"
1321 << "\n"
1322 << "void main (void)\n"
1323 << "{\n"
1324 << " float u = gl_TessCoord.x;\n"
1325 << " float v = gl_TessCoord.y;\n"
1326 << " float omu = 1.0f - u;\n"
1327 << " float omv = 1.0f - v;\n"
1328 << " gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * "
1329 "gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
1330 << " gl_Position.x *= 1.5f;\n"
1331 << "}\n";
1332
1333 geom << "#version 450\n"
1334 << "layout(triangles) in;\n"
1335 << "layout(triangle_strip, max_vertices = 4) out;\n"
1336 << "layout(set = 0, binding = 0) buffer Output {\n"
1337 << " uint values[4];\n"
1338 << "} buffer_out;\n\n"
1339 << "\n"
1340 << "void main(void)\n"
1341 << "{\n"
1342 << " gl_Position = gl_in[0].gl_Position;\n"
1343 << " gl_Position.y *= 1.5f;\n"
1344 << " EmitVertex();\n"
1345 << " gl_Position = gl_in[1].gl_Position;\n"
1346 << " gl_Position.y *= 1.5f;\n"
1347 << " EmitVertex();\n"
1348 << " gl_Position = gl_in[2].gl_Position;\n"
1349 << " gl_Position.y *= 1.5f;\n"
1350 << " EmitVertex();\n"
1351 << " EndPrimitive();\n"
1352 << " if (gl_InvocationID == 0u)\n"
1353 << " buffer_out.values[2] = 3u;\n"
1354 << "}\n";
1355
1356 frag << "#version 450\n"
1357 << "layout (location=0) out vec4 outColor;\n"
1358 << "void main() {\n"
1359 << " outColor = vec4(1.0f);\n"
1360 << "}\n";
1361
1362 pipeline_vert << "#version 450\n"
1363 << "void main() {\n"
1364 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
1365 << " gl_Position = vec4(pos - 0.5f, 0.0f, 1.0f);\n"
1366 << "}\n";
1367
1368 pipeline_tesc << "#version 450\n"
1369 << "\n"
1370 << "layout(vertices = 4) out;\n"
1371 << "\n"
1372 << "void main (void)\n"
1373 << "{\n"
1374 << " if (gl_InvocationID == 0) {\n"
1375 << " gl_TessLevelInner[0] = 1.0;\n"
1376 << " gl_TessLevelInner[1] = 1.0;\n"
1377 << " gl_TessLevelOuter[0] = 1.0;\n"
1378 << " gl_TessLevelOuter[1] = 1.0;\n"
1379 << " gl_TessLevelOuter[2] = 1.0;\n"
1380 << " gl_TessLevelOuter[3] = 1.0;\n"
1381 << " }\n"
1382 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1383 << "}\n";
1384
1385 pipeline_tese << "#version 450\n"
1386 << "\n"
1387 << "layout(quads, equal_spacing) in;\n"
1388 << "\n"
1389 << "void main (void)\n"
1390 << "{\n"
1391 << " float u = gl_TessCoord.x;\n"
1392 << " float v = gl_TessCoord.y;\n"
1393 << " float omu = 1.0f - u;\n"
1394 << " float omv = 1.0f - v;\n"
1395 << " gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * "
1396 "gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
1397 << " gl_Position.x *= 0.5f;\n"
1398 << " gl_Position.y *= 0.5f;\n"
1399 << "}\n";
1400
1401 pipeline_geom << "#version 450\n"
1402 << "layout(triangles) in;\n"
1403 << "layout(triangle_strip, max_vertices = 4) out;\n"
1404 << "\n"
1405 << "void main(void)\n"
1406 << "{\n"
1407 << " gl_Position = gl_in[0].gl_Position;\n"
1408 << " gl_Position.x += 0.25f;\n"
1409 << " gl_Position.y += 0.25f;\n"
1410 << " EmitVertex();\n"
1411 << " gl_Position = gl_in[1].gl_Position;\n"
1412 << " gl_Position.x += 0.25f;\n"
1413 << " gl_Position.y += 0.25f;\n"
1414 << " EmitVertex();\n"
1415 << " gl_Position = gl_in[2].gl_Position;\n"
1416 << " gl_Position.x += 0.25f;\n"
1417 << " gl_Position.y += 0.25f;\n"
1418 << " EmitVertex();\n"
1419 << " EndPrimitive();\n"
1420 << "}\n";
1421
1422 pipeline_frag << "#version 450\n"
1423 << "layout (location=0) out vec4 outColor;\n"
1424 << "void main() {\n"
1425 << " outColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n"
1426 << "}\n";
1427
1428 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
1429 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
1430 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
1431 programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
1432 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
1433
1434 programCollection.glslSources.add("pipeline_vert") << glu::VertexSource(pipeline_vert.str());
1435 programCollection.glslSources.add("pipeline_tesc") << glu::TessellationControlSource(pipeline_tesc.str());
1436 programCollection.glslSources.add("pipeline_tese") << glu::TessellationEvaluationSource(pipeline_tese.str());
1437 programCollection.glslSources.add("pipeline_geom") << glu::GeometrySource(pipeline_geom.str());
1438 programCollection.glslSources.add("pipeline_frag") << glu::FragmentSource(pipeline_frag.str());
1439 }
1440
1441 } // namespace
1442
createShaderObjectPipelineInteractionTests(tcu::TestContext & testCtx)1443 tcu::TestCaseGroup *createShaderObjectPipelineInteractionTests(tcu::TestContext &testCtx)
1444 {
1445 de::MovePtr<tcu::TestCaseGroup> pipelineInteractionGroup(new tcu::TestCaseGroup(testCtx, "pipeline_interaction"));
1446
1447 const struct
1448 {
1449 TestType testType;
1450 const char *name;
1451 } tests[] = {
1452 {SHADER_OBJECT, "shader_object"},
1453 {MAX_PIPELINE, "max_pipeline"},
1454 {MAX_PIPELINE_SHADER_OBJECT_MAX_PIPELINE, "max_pipeline_shader_object_max_pipeline"},
1455 {SHADER_OBJECT_MAX_PIPELINE_SHADER_OBJECT, "shader_object_max_pipeline_shader_object"},
1456 {MIN_PIPELINE_SHADER_OBJECT, "min_pipeline_shader_object"},
1457 {SHADER_OBJECT_MIN_PIPELINE, "shader_object_min_pipeline"},
1458 {RENDER_PASS_PIPELINE_SHADER_OBJECT, "render_pass_pipeline_shader_object"},
1459 {RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN, "render_pass_pipeline_shader_object_after_begin"},
1460 {COMPUTE_SHADER_OBJECT_MIN_PIPELINE, "compute_shader_object_min_pipeline"},
1461 {SHADER_OBJECT_COMPUTE_PIPELINE, "shader_object_compute_pipeline"},
1462 };
1463
1464 for (const auto &test : tests)
1465 {
1466 TestParams params;
1467 params.testType = test.testType;
1468
1469 pipelineInteractionGroup->addChild(new ShaderObjectPipelineInteractionCase(testCtx, test.name, params));
1470 }
1471
1472 const struct
1473 {
1474 StageTestParams shaders;
1475 const char *name;
1476 } shaderBindTests[] = {
1477 {{true, false, false, false}, "vert"}, {{true, true, false, false}, "vert_tess"},
1478 {{true, false, true, false}, "vert_geom"}, {{true, false, false, true}, "vert_frag"},
1479 {{true, true, true, false}, "vert_tess_geom"}, {{true, true, false, true}, "vert_tess_frag"},
1480 {{true, false, true, true}, "vert_geom_frag"}, {{true, true, true, true}, "vert_tess_geom_frag"},
1481 };
1482
1483 for (const auto &shaderBindTest : shaderBindTests)
1484 {
1485 pipelineInteractionGroup->addChild(
1486 new ShaderObjectStageBindingCase(testCtx, shaderBindTest.name, shaderBindTest.shaders));
1487 }
1488
1489 return pipelineInteractionGroup.release();
1490 }
1491
1492 } // namespace ShaderObject
1493 } // namespace vkt
1494