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 37namespace vkt 38{ 39namespace ShaderObject 40{ 41 42namespace 43{ 44 45enum 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 58struct TestParams { 59 TestType testType; 60}; 61 62struct StageTestParams { 63 bool vertShader; 64 bool tessShader; 65 bool geomShader; 66 bool fragShader; 67}; 68 69class ShaderObjectPipelineInteractionInstance : public vkt::TestInstance 70{ 71public: 72 ShaderObjectPipelineInteractionInstance (Context& context, const TestParams& params) 73 : vkt::TestInstance (context) 74 , m_params (params) 75 {} 76 virtual ~ShaderObjectPipelineInteractionInstance (void) {} 77 78 tcu::TestStatus iterate (void) override; 79private: 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 88deUint32 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 115bool 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 120tcu::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 618bool 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 654class ShaderObjectPipelineInteractionCase : public vkt::TestCase 655{ 656public: 657 ShaderObjectPipelineInteractionCase (tcu::TestContext& testCtx, const std::string& name, const TestParams& params) 658 : vkt::TestCase (testCtx, name) 659 , m_params (params) 660 {} 661 virtual ~ShaderObjectPipelineInteractionCase (void) {} 662 663 void checkSupport (vkt::Context& context) const override; 664 virtual void initPrograms (vk::SourceCollections& programCollection) const override; 665 TestInstance* createInstance (Context& context) const override { return new ShaderObjectPipelineInteractionInstance(context, m_params); } 666private: 667 TestParams m_params; 668}; 669 670void 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 791void 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 800class ShaderObjectStageBindingInstance : public vkt::TestInstance 801{ 802public: 803 ShaderObjectStageBindingInstance (Context& context, const StageTestParams& params) 804 : vkt::TestInstance (context) 805 , m_params (params) 806 {} 807 virtual ~ShaderObjectStageBindingInstance (void) {} 808 809 tcu::TestStatus iterate (void) override; 810private: 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 818tcu::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 1074bool 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 1107class ShaderObjectStageBindingCase : public vkt::TestCase 1108{ 1109public: 1110 ShaderObjectStageBindingCase (tcu::TestContext& testCtx, const std::string& name, const StageTestParams& params) 1111 : vkt::TestCase (testCtx, name) 1112 , m_params (params) 1113 {} 1114 virtual ~ShaderObjectStageBindingCase (void) {} 1115 1116 void checkSupport (vkt::Context& context) const override; 1117 virtual void initPrograms (vk::SourceCollections& programCollection) const override; 1118 TestInstance* createInstance (Context& context) const override { return new ShaderObjectStageBindingInstance(context, m_params); } 1119private: 1120 StageTestParams m_params; 1121}; 1122 1123void 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 1134void 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 1313tcu::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