• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:					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 
getShaderObjectNextStages(vk::VkShaderStageFlagBits shaderStage,bool tessellationShaderFeature,bool geometryShaderFeature)50 vk::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 
createShaderFromBinary(const DeviceInterface & vk,VkDevice device,vk::VkShaderStageFlagBits shaderStage,size_t codeSize,const void * pCode,bool tessellationShaderFeature,bool geometryShaderFeature,vk::VkDescriptorSetLayout descriptorSetLayout)87 Move<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 
createShader(const DeviceInterface & vk,VkDevice device,const vk::VkShaderCreateInfoEXT & shaderCreateInfo)110 Move<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 
addBasicShaderObjectShaders(vk::SourceCollections & programCollection)117 void 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 
makeShaderCreateInfo(vk::VkShaderStageFlagBits stage,const vk::ProgramBinary & programBinary,bool tessellationShaderFeature,bool geometryShaderFeature,const vk::VkDescriptorSetLayout * descriptorSetLayout)213 vk::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 
extensionEnabled(const std::vector<std::string> & deviceExtensions,const std::string & ext)236 bool 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 
setDefaultShaderObjectDynamicStates(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,const std::vector<std::string> & deviceExtensions,vk::VkPrimitiveTopology topology,bool meshShader,bool setViewport)241 void 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 
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)397 void 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 
bindComputeShader(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkShaderEXT compShader)426 void 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 
bindNullTaskMeshShaders(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkPhysicalDeviceMeshShaderFeaturesEXT meshShaderFeatures)432 void 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 
bindNullRasterizationShaders(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkPhysicalDeviceFeatures features)445 void 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