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