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 Utilities for vertex buffers. 23 *//*--------------------------------------------------------------------*/ 24 25#include "vktShaderObjectCreateUtil.hpp" 26#include "vktTestCase.hpp" 27 28namespace vk 29{ 30 31std::string getShaderName (vk::VkShaderStageFlagBits stage) 32{ 33 switch (stage) 34 { 35 case vk::VK_SHADER_STAGE_VERTEX_BIT: return "vert"; 36 case vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return "tesc"; 37 case vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return "tese"; 38 case vk::VK_SHADER_STAGE_GEOMETRY_BIT: return "geom"; 39 case vk::VK_SHADER_STAGE_FRAGMENT_BIT: return "frag"; 40 case vk::VK_SHADER_STAGE_COMPUTE_BIT: return "comp"; 41 case vk::VK_SHADER_STAGE_MESH_BIT_EXT: return "mesh"; 42 case vk::VK_SHADER_STAGE_TASK_BIT_EXT: return "task"; 43 default: 44 DE_ASSERT(false); 45 break; 46 } 47 return {}; 48} 49 50vk::VkShaderStageFlags getShaderObjectNextStages (vk::VkShaderStageFlagBits shaderStage, bool tessellationShaderFeature, bool geometryShaderFeature) 51{ 52 if (shaderStage == vk::VK_SHADER_STAGE_VERTEX_BIT) 53 { 54 vk::VkShaderStageFlags flags = vk::VK_SHADER_STAGE_FRAGMENT_BIT; 55 if (tessellationShaderFeature) 56 flags |= vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; 57 if (geometryShaderFeature) 58 flags |= vk::VK_SHADER_STAGE_GEOMETRY_BIT; 59 return flags; 60 } 61 else if (shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) 62 { 63 return vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; 64 } 65 else if (shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) 66 { 67 vk::VkShaderStageFlags flags = vk::VK_SHADER_STAGE_FRAGMENT_BIT; 68 if (geometryShaderFeature) 69 flags |= vk::VK_SHADER_STAGE_GEOMETRY_BIT; 70 return flags; 71 } 72 else if (shaderStage == vk::VK_SHADER_STAGE_GEOMETRY_BIT) 73 { 74 return vk::VK_SHADER_STAGE_FRAGMENT_BIT; 75 } 76 else if (shaderStage == vk::VK_SHADER_STAGE_TASK_BIT_EXT) 77 { 78 return vk::VK_SHADER_STAGE_MESH_BIT_EXT; 79 } 80 else if (shaderStage == vk::VK_SHADER_STAGE_MESH_BIT_EXT) 81 { 82 return vk::VK_SHADER_STAGE_FRAGMENT_BIT; 83 } 84 return 0; 85} 86 87Move<VkShaderEXT> createShaderFromBinary (const DeviceInterface& vk, VkDevice device, vk::VkShaderStageFlagBits shaderStage, size_t codeSize, const void* pCode, bool tessellationShaderFeature, bool geometryShaderFeature, vk::VkDescriptorSetLayout descriptorSetLayout) 88{ 89 vk::VkShaderCreateInfoEXT pCreateInfo = 90 { 91 vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT, // VkStructureType sType; 92 DE_NULL, // const void* pNext; 93 0u, // VkShaderCreateFlagsEXT flags; 94 shaderStage, // VkShaderStageFlagBits stage; 95 getShaderObjectNextStages(shaderStage, tessellationShaderFeature, geometryShaderFeature), // VkShaderStageFlags nextStage; 96 vk::VK_SHADER_CODE_TYPE_BINARY_EXT, // VkShaderCodeTypeEXT codeType; 97 codeSize, // size_t codeSize; 98 pCode, // const void* pCode; 99 "main", // const char* pName; 100 (descriptorSetLayout != VK_NULL_HANDLE) ? 1u : 0u, // uint32_t setLayoutCount; 101 (descriptorSetLayout != VK_NULL_HANDLE) ? &descriptorSetLayout : DE_NULL, // VkDescriptorSetLayout* pSetLayouts; 102 0u, // uint32_t pushConstantRangeCount; 103 DE_NULL, // const VkPushConstantRange* pPushConstantRanges; 104 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; 105 }; 106 107 return createShader(vk, device, pCreateInfo); 108} 109 110Move<VkShaderEXT> createShader (const DeviceInterface& vk, VkDevice device, const vk::VkShaderCreateInfoEXT& shaderCreateInfo) 111{ 112 VkShaderEXT object = VK_NULL_HANDLE; 113 VK_CHECK(vk.createShadersEXT(device, 1u, &shaderCreateInfo, DE_NULL, &object)); 114 return Move<VkShaderEXT>(check<VkShaderEXT>(object), Deleter<VkShaderEXT>(vk, device, DE_NULL)); 115} 116 117void addBasicShaderObjectShaders (vk::SourceCollections& programCollection) 118{ 119 std::stringstream vert; 120 std::stringstream geom; 121 std::stringstream tesc; 122 std::stringstream tese; 123 std::stringstream frag; 124 std::stringstream comp; 125 126 vert 127 << "#version 450\n" 128 << "void main() {\n" 129 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n" 130 << " gl_Position = vec4(pos - 0.5f, 0.0f, 1.0f);\n" 131 << "}\n"; 132 133 tesc 134 << "#version 450\n" 135 << "\n" 136 << "layout(vertices = 4) out;\n" 137 << "\n" 138 << "void main (void)\n" 139 << "{\n" 140 << " if (gl_InvocationID == 0) {\n" 141 << " gl_TessLevelInner[0] = 1.0;\n" 142 << " gl_TessLevelInner[1] = 1.0;\n" 143 << " gl_TessLevelOuter[0] = 1.0;\n" 144 << " gl_TessLevelOuter[1] = 1.0;\n" 145 << " gl_TessLevelOuter[2] = 1.0;\n" 146 << " gl_TessLevelOuter[3] = 1.0;\n" 147 << " }\n" 148 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 149 << "}\n"; 150 151 tese 152 << "#version 450\n" 153 << "\n" 154 << "layout(quads, equal_spacing) in;\n" 155 << "\n" 156 << "void main (void)\n" 157 << "{\n" 158 << " float u = gl_TessCoord.x;\n" 159 << " float v = gl_TessCoord.y;\n" 160 << " float omu = 1.0f - u;\n" 161 << " float omv = 1.0f - v;\n" 162 << " 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" 163 << " gl_Position.x *= 1.5f;\n" 164 << "}\n"; 165 166 geom 167 << "#version 450\n" 168 << "layout(triangles) in;\n" 169 << "layout(triangle_strip, max_vertices = 4) out;\n" 170 << "\n" 171 << "void main(void)\n" 172 << "{\n" 173 << " gl_Position = gl_in[0].gl_Position;\n" 174 << " gl_Position.y *= 1.5f;\n" 175 << " gl_Position.z = 0.5f;\n" 176 << " EmitVertex();\n" 177 << " gl_Position = gl_in[1].gl_Position;\n" 178 << " gl_Position.y *= 1.5f;\n" 179 << " gl_Position.z = 0.5f;\n" 180 << " EmitVertex();\n" 181 << " gl_Position = gl_in[2].gl_Position;\n" 182 << " gl_Position.y *= 1.5f;\n" 183 << " gl_Position.z = 0.5f;\n" 184 << " EmitVertex();\n" 185 << " EndPrimitive();\n" 186 << "}\n"; 187 188 frag 189 << "#version 450\n" 190 << "layout (location=0) out vec4 outColor;\n" 191 << "void main() {\n" 192 << " outColor = vec4(1.0f);\n" 193 << "}\n"; 194 195 comp 196 << "#version 450\n" 197 << "layout(local_size_x=16, local_size_x=1, local_size_x=1) in;\n" 198 << "layout(binding = 0) buffer Output {\n" 199 << " uint values[16];\n" 200 << "} buffer_out;\n\n" 201 << "void main() {\n" 202 << " buffer_out.values[gl_LocalInvocationID.x] = gl_LocalInvocationID.x;\n" 203 << "}\n"; 204 205 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str()); 206 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str()); 207 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str()); 208 programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str()); 209 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str()); 210 programCollection.glslSources.add("comp") << glu::ComputeSource(comp.str()); 211} 212 213vk::VkShaderCreateInfoEXT makeShaderCreateInfo (vk::VkShaderStageFlagBits stage, const vk::ProgramBinary& programBinary, bool tessellationShaderFeature, bool geometryShaderFeature, const vk::VkDescriptorSetLayout* descriptorSetLayout) 214{ 215 vk::VkShaderCreateInfoEXT shaderCreateInfo = 216 { 217 vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT, // VkStructureType sType; 218 DE_NULL, // const void* pNext; 219 0u, // VkShaderCreateFlagsEXT flags; 220 stage, // VkShaderStageFlagBits stage; 221 vk::getShaderObjectNextStages(stage, tessellationShaderFeature, geometryShaderFeature), // VkShaderStageFlags nextStage; 222 vk::VK_SHADER_CODE_TYPE_SPIRV_EXT, // VkShaderCodeTypeEXT codeType; 223 programBinary.getSize(), // size_t codeSize; 224 programBinary.getBinary(), // const void* pCode; 225 "main", // const char* pName; 226 (descriptorSetLayout != DE_NULL) ? 1u : 0u, // uint32_t setLayoutCount; 227 (descriptorSetLayout != DE_NULL) ? descriptorSetLayout : DE_NULL, // VkDescriptorSetLayout* pSetLayouts; 228 0u, // uint32_t pushConstantRangeCount; 229 DE_NULL, // const VkPushConstantRange* pPushConstantRanges; 230 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; 231 }; 232 233 return shaderCreateInfo; 234} 235 236bool extensionEnabled(const std::vector<std::string>& deviceExtensions, const std::string& ext) 237{ 238 return std::find(deviceExtensions.begin(), deviceExtensions.end(), ext) != deviceExtensions.end(); 239} 240 241void setDefaultShaderObjectDynamicStates (const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, const std::vector<std::string>& deviceExtensions, vk::VkPrimitiveTopology topology, bool meshShader, bool setViewport) 242{ 243 vk::VkViewport viewport = { 0, 0, 32, 32, 0.0f, 1.0f, }; 244 if (setViewport) 245 vk.cmdSetViewport(cmdBuffer, 0u, 1u, &viewport); 246 vk.cmdSetViewportWithCount(cmdBuffer, 1u, &viewport); 247 vk::VkRect2D scissor = { { 0, 0, }, { 32, 32, }, }; 248 if (setViewport) 249 vk.cmdSetScissor(cmdBuffer, 0u, 1u, &scissor); 250 vk.cmdSetScissorWithCount(cmdBuffer, 1u, &scissor); 251 vk.cmdSetLineWidth(cmdBuffer, 1.0f); 252 vk.cmdSetDepthBias(cmdBuffer, 1.0f, 1.0f, 1.0f); 253 float blendConstants[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; 254 vk.cmdSetBlendConstants(cmdBuffer, blendConstants); 255 vk.cmdSetDepthBounds(cmdBuffer, 0.0f, 1.0f); 256 vk.cmdSetStencilCompareMask(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFFFFFFF); 257 vk.cmdSetStencilWriteMask(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFFFFFFF); 258 vk.cmdSetStencilReference(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFFFFFFF); 259 vk.cmdBindVertexBuffers2(cmdBuffer, 0, 0, DE_NULL, DE_NULL, DE_NULL, DE_NULL); 260 vk.cmdSetCullMode(cmdBuffer, vk::VK_CULL_MODE_NONE); 261 vk.cmdSetDepthBoundsTestEnable(cmdBuffer, VK_FALSE); 262 vk.cmdSetDepthCompareOp(cmdBuffer, vk::VK_COMPARE_OP_NEVER); 263 vk.cmdSetDepthTestEnable(cmdBuffer, VK_FALSE); 264 vk.cmdSetDepthWriteEnable(cmdBuffer, VK_FALSE); 265 vk.cmdSetFrontFace(cmdBuffer, vk::VK_FRONT_FACE_CLOCKWISE); 266 if (!meshShader) 267 vk.cmdSetPrimitiveTopology(cmdBuffer, topology); 268 vk.cmdSetStencilOp(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_NEVER); 269 vk.cmdSetStencilTestEnable(cmdBuffer, VK_FALSE); 270 vk.cmdSetDepthBiasEnable(cmdBuffer, VK_FALSE); 271 if (!meshShader) 272 vk.cmdSetPrimitiveRestartEnable(cmdBuffer, VK_FALSE); 273 vk.cmdSetRasterizerDiscardEnable(cmdBuffer, VK_FALSE); 274 if (!meshShader && (extensionEnabled(deviceExtensions, "VK_EXT_shader_object") || extensionEnabled(deviceExtensions, "VK_EXT_vertex_input_dynamic_state"))) 275 vk.cmdSetVertexInputEXT(cmdBuffer, 0u, DE_NULL, 0u, DE_NULL); 276 vk.cmdSetLogicOpEXT(cmdBuffer, vk::VK_LOGIC_OP_AND); 277 if (!meshShader) 278 vk.cmdSetPatchControlPointsEXT(cmdBuffer, 4u); 279 vk.cmdSetTessellationDomainOriginEXT(cmdBuffer, vk::VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT); 280 vk.cmdSetDepthClampEnableEXT(cmdBuffer, VK_FALSE); 281 vk.cmdSetPolygonModeEXT(cmdBuffer, vk::VK_POLYGON_MODE_FILL); 282 vk.cmdSetRasterizationSamplesEXT(cmdBuffer, vk::VK_SAMPLE_COUNT_1_BIT); 283 vk::VkSampleMask sampleMask = 0xFFFFFFFF; 284 vk.cmdSetSampleMaskEXT(cmdBuffer, vk::VK_SAMPLE_COUNT_1_BIT, &sampleMask); 285 vk.cmdSetAlphaToCoverageEnableEXT(cmdBuffer, VK_FALSE); 286 vk.cmdSetAlphaToOneEnableEXT(cmdBuffer, VK_FALSE); 287 vk.cmdSetLogicOpEnableEXT(cmdBuffer, VK_FALSE); 288 vk::VkBool32 colorBlendEnable = VK_FALSE; 289 vk.cmdSetColorBlendEnableEXT(cmdBuffer, 0u, 1u, &colorBlendEnable); 290 vk::VkColorBlendEquationEXT colorBlendEquation = { 291 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; 292 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor; 293 vk::VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 294 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 295 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor; 296 vk::VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 297 }; 298 vk.cmdSetColorBlendEquationEXT(cmdBuffer, 0u, 1u, &colorBlendEquation); 299 vk::VkColorComponentFlags colorWriteMask = vk::VK_COLOR_COMPONENT_R_BIT | vk::VK_COLOR_COMPONENT_G_BIT | 300 vk::VK_COLOR_COMPONENT_B_BIT | vk::VK_COLOR_COMPONENT_A_BIT; 301 vk.cmdSetColorWriteMaskEXT(cmdBuffer, 0u, 1u, &colorWriteMask); 302 vk::VkExtent2D fragmentSize = { 1u, 1u }; 303 vk::VkFragmentShadingRateCombinerOpKHR combinerOps[2] = { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR }; 304 if (extensionEnabled(deviceExtensions, "VK_KHR_fragment_shading_rate")) 305 vk.cmdSetFragmentShadingRateKHR(cmdBuffer, &fragmentSize, combinerOps); 306 if (extensionEnabled(deviceExtensions, "VK_EXT_transform_feedback")) 307 vk.cmdSetRasterizationStreamEXT(cmdBuffer, 0); 308 if (extensionEnabled(deviceExtensions, "VK_EXT_conservative_rasterization")) 309 vk.cmdSetConservativeRasterizationModeEXT(cmdBuffer, vk::VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT); 310 if (extensionEnabled(deviceExtensions, "VK_EXT_conservative_rasterization")) 311 vk.cmdSetExtraPrimitiveOverestimationSizeEXT(cmdBuffer, 0.0f); 312 if (extensionEnabled(deviceExtensions, "VK_EXT_depth_clip_enable")) 313 vk.cmdSetDepthClipEnableEXT(cmdBuffer, VK_FALSE); 314 if (extensionEnabled(deviceExtensions, "VK_EXT_sample_locations")) 315 vk.cmdSetSampleLocationsEnableEXT(cmdBuffer, VK_FALSE); 316 VkSampleLocationEXT sampleLocation = { 0.5f, 0.5f }; 317 const vk::VkSampleLocationsInfoEXT sampleLocations = 318 { 319 vk::VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT, // VkStructureType sType; 320 DE_NULL, // const void* pNext; 321 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits sampleLocationsPerPixel; 322 { 1u, 1u }, // VkExtent2D sampleLocationGridSize; 323 1, // uint32_t sampleLocationsCount; 324 &sampleLocation, // const VkSampleLocationEXT* pSampleLocations; 325 }; 326 if (extensionEnabled(deviceExtensions, "VK_EXT_sample_locations")) 327 vk.cmdSetSampleLocationsEXT(cmdBuffer, &sampleLocations); 328 vk::VkColorBlendAdvancedEXT colorBlendAdvanced; 329 colorBlendAdvanced.advancedBlendOp = vk::VK_BLEND_OP_SRC_EXT; 330 colorBlendAdvanced.srcPremultiplied = VK_FALSE; 331 colorBlendAdvanced.dstPremultiplied = VK_FALSE; 332 colorBlendAdvanced.blendOverlap = vk::VK_BLEND_OVERLAP_UNCORRELATED_EXT; 333 colorBlendAdvanced.clampResults = VK_FALSE; 334 if (extensionEnabled(deviceExtensions, "VK_EXT_blend_operation_advanced")) 335 vk.cmdSetColorBlendAdvancedEXT(cmdBuffer, 0, 1, &colorBlendAdvanced); 336 if (extensionEnabled(deviceExtensions, "VK_EXT_provoking_vertex")) 337 vk.cmdSetProvokingVertexModeEXT(cmdBuffer, vk::VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT); 338 if (extensionEnabled(deviceExtensions, "VK_EXT_line_rasterization")) 339 vk.cmdSetLineRasterizationModeEXT(cmdBuffer, vk::VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT); 340 if (extensionEnabled(deviceExtensions, "VK_EXT_line_rasterization")) 341 vk.cmdSetLineStippleEnableEXT(cmdBuffer, VK_FALSE); 342 if (extensionEnabled(deviceExtensions, "VK_EXT_line_rasterization")) 343 vk.cmdSetLineStippleEXT(cmdBuffer, 1u, 0x0F0F); 344 if (extensionEnabled(deviceExtensions, "VK_EXT_depth_clip_control")) 345 vk.cmdSetDepthClipNegativeOneToOneEXT(cmdBuffer, VK_FALSE); 346 VkBool32 colorWriteEnable = VK_TRUE; 347 if (extensionEnabled(deviceExtensions, "VK_EXT_color_write_enable")) 348 vk.cmdSetColorWriteEnableEXT(cmdBuffer, 1, &colorWriteEnable); 349 if (extensionEnabled(deviceExtensions, "VK_NV_clip_space_w_scaling")) 350 vk.cmdSetViewportWScalingEnableNV(cmdBuffer, VK_FALSE); 351 vk::VkViewportWScalingNV viewportWScaling = { 1.0f, 1.0f }; 352 if (extensionEnabled(deviceExtensions, "VK_NV_clip_space_w_scaling")) 353 vk.cmdSetViewportWScalingNV(cmdBuffer, 0, 1, &viewportWScaling); 354 vk::VkViewportSwizzleNV viewportSwizzle; 355 viewportSwizzle.x = VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV; 356 viewportSwizzle.y = VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV; 357 viewportSwizzle.z = VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV; 358 viewportSwizzle.w = VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV; 359 if (extensionEnabled(deviceExtensions, "VK_NV_viewport_swizzle")) 360 vk.cmdSetViewportSwizzleNV(cmdBuffer, 0, 1, &viewportSwizzle); 361 if (extensionEnabled(deviceExtensions, "VK_NV_fragment_coverage_to_color")) 362 vk.cmdSetCoverageToColorEnableNV(cmdBuffer, VK_FALSE); 363 if (extensionEnabled(deviceExtensions, "VK_NV_fragment_coverage_to_color")) 364 vk.cmdSetCoverageToColorLocationNV(cmdBuffer, 0); 365 if (extensionEnabled(deviceExtensions, "VK_NV_framebuffer_mixed_samples")) 366 vk.cmdSetCoverageModulationModeNV(cmdBuffer, vk::VK_COVERAGE_MODULATION_MODE_NONE_NV); 367 if (extensionEnabled(deviceExtensions, "VK_NV_framebuffer_mixed_samples")) 368 vk.cmdSetCoverageModulationTableEnableNV(cmdBuffer, VK_FALSE); 369 float coverageModulationTable = 1.0f; 370 if (extensionEnabled(deviceExtensions, "VK_NV_framebuffer_mixed_samples")) 371 vk.cmdSetCoverageModulationTableNV(cmdBuffer, 1, &coverageModulationTable); 372 if (extensionEnabled(deviceExtensions, "VK_NV_shading_rate_image")) 373 vk.cmdSetShadingRateImageEnableNV(cmdBuffer, VK_FALSE); 374 if (extensionEnabled(deviceExtensions, "VK_NV_coverage_reduction_mode")) 375 vk.cmdSetCoverageReductionModeNV(cmdBuffer, vk::VK_COVERAGE_REDUCTION_MODE_MERGE_NV); 376 if (extensionEnabled(deviceExtensions, "VK_NV_representative_fragment_test")) 377 vk.cmdSetRepresentativeFragmentTestEnableNV(cmdBuffer, VK_FALSE); 378 vk::VkBool32 scissorEnable = VK_FALSE; 379 if (extensionEnabled(deviceExtensions, "VK_NV_scissor_exclusive")) 380 vk.cmdSetExclusiveScissorEnableNV(cmdBuffer, 0u, 1u, &scissorEnable); 381 if (extensionEnabled(deviceExtensions, "VK_NV_scissor_exclusive")) 382 vk.cmdSetExclusiveScissorNV(cmdBuffer, 0u, 1u, &scissor); 383 if (extensionEnabled(deviceExtensions, "VK_NV_fragment_shading_rate_enums")) 384 vk.cmdSetFragmentShadingRateEnumNV(cmdBuffer, vk::VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV, combinerOps); 385 if (extensionEnabled(deviceExtensions, "VK_EXT_discard_rectangles")) 386 vk.cmdSetDiscardRectangleEnableEXT(cmdBuffer, VK_FALSE); 387 if (extensionEnabled(deviceExtensions, "VK_EXT_discard_rectangles")) 388 vk.cmdSetDiscardRectangleEXT(cmdBuffer, 0u, 1u, &scissor); 389 if (extensionEnabled(deviceExtensions, "VK_EXT_discard_rectangles")) 390 vk.cmdSetDiscardRectangleModeEXT(cmdBuffer, vk::VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT); 391 if (extensionEnabled(deviceExtensions, "VK_NV_shading_rate_image")) 392 vk.cmdSetShadingRateImageEnableNV(cmdBuffer, VK_FALSE); 393 if (extensionEnabled(deviceExtensions, "VK_EXT_attachment_feedback_loop_dynamic_state")) 394 vk.cmdSetAttachmentFeedbackLoopEnableEXT(cmdBuffer, 0u); 395} 396 397void bindGraphicsShaders (const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkShaderEXT vertShader, vk::VkShaderEXT tescShader, vk::VkShaderEXT teseShader, vk::VkShaderEXT geomShader, vk::VkShaderEXT fragShader, bool taskShaderSupported, bool meshShaderSupported) 398{ 399 vk::VkShaderStageFlagBits stages[] = { 400 vk::VK_SHADER_STAGE_VERTEX_BIT, 401 vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 402 vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 403 vk::VK_SHADER_STAGE_GEOMETRY_BIT, 404 vk::VK_SHADER_STAGE_FRAGMENT_BIT, 405 }; 406 vk::VkShaderEXT shaders[] = { 407 vertShader, 408 tescShader, 409 teseShader, 410 geomShader, 411 fragShader, 412 }; 413 vk.cmdBindShadersEXT(cmdBuffer, 5u, stages, shaders); 414 if (taskShaderSupported) { 415 vk::VkShaderStageFlagBits stage = vk::VK_SHADER_STAGE_TASK_BIT_EXT; 416 vk::VkShaderEXT shader = VK_NULL_HANDLE; 417 vk.cmdBindShadersEXT(cmdBuffer, 1u, &stage, &shader); 418 } 419 if (meshShaderSupported) { 420 vk::VkShaderStageFlagBits stage = vk::VK_SHADER_STAGE_MESH_BIT_EXT; 421 vk::VkShaderEXT shader = VK_NULL_HANDLE; 422 vk.cmdBindShadersEXT(cmdBuffer, 1u, &stage, &shader); 423 } 424} 425 426void bindComputeShader (const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkShaderEXT compShader) 427{ 428 vk::VkShaderStageFlagBits stage = vk::VK_SHADER_STAGE_COMPUTE_BIT; 429 vk.cmdBindShadersEXT(cmdBuffer, 1, &stage, &compShader); 430} 431 432void bindNullTaskMeshShaders (const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkPhysicalDeviceMeshShaderFeaturesEXT meshShaderFeatures) 433{ 434 vk::VkShaderEXT shader = VK_NULL_HANDLE; 435 vk::VkShaderStageFlagBits taskStage = vk::VK_SHADER_STAGE_TASK_BIT_EXT; 436 vk::VkShaderStageFlagBits meshStage = vk::VK_SHADER_STAGE_MESH_BIT_EXT; 437 if (meshShaderFeatures.taskShader) { 438 vk.cmdBindShadersEXT(cmdBuffer, 1u, &taskStage, &shader); 439 } 440 if (meshShaderFeatures.meshShader) { 441 vk.cmdBindShadersEXT(cmdBuffer, 1u, &meshStage, &shader); 442 } 443} 444 445void bindNullRasterizationShaders (const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkPhysicalDeviceFeatures features) 446{ 447 vk::VkShaderEXT shader = VK_NULL_HANDLE; 448 vk::VkShaderStageFlagBits vertStage = vk::VK_SHADER_STAGE_VERTEX_BIT; 449 vk::VkShaderStageFlagBits tescStage = vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; 450 vk::VkShaderStageFlagBits teseStage = vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; 451 vk::VkShaderStageFlagBits geomStage = vk::VK_SHADER_STAGE_GEOMETRY_BIT; 452 vk.cmdBindShadersEXT(cmdBuffer, 1u, &vertStage, &shader); 453 if (features.tessellationShader) { 454 vk.cmdBindShadersEXT(cmdBuffer, 1u, &tescStage, &shader); 455 vk.cmdBindShadersEXT(cmdBuffer, 1u, &teseStage, &shader); 456 } 457 if (features.geometryShader) { 458 vk.cmdBindShadersEXT(cmdBuffer, 1u, &geomStage, &shader); 459 } 460} 461 462} // vk 463