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