1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2016 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Pipeline specialization constants test utilities
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktPipelineSpecConstantUtil.hpp"
25 #include "vkTypeUtil.hpp"
26 #include <vector>
27
28 namespace vkt
29 {
30 namespace pipeline
31 {
32 using namespace vk;
33
setShader(const DeviceInterface & vk,const VkDevice device,const VkShaderStageFlagBits stage,const ProgramBinary & binary,const VkSpecializationInfo * specInfo)34 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface& vk,
35 const VkDevice device,
36 const VkShaderStageFlagBits stage,
37 const ProgramBinary& binary,
38 const VkSpecializationInfo* specInfo)
39 {
40 VkShaderModule module;
41 switch (stage)
42 {
43 case (VK_SHADER_STAGE_VERTEX_BIT):
44 DE_ASSERT(m_vertexShaderModule.get() == DE_NULL);
45 m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
46 module = *m_vertexShaderModule;
47 break;
48
49 case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT):
50 DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL);
51 m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
52 module = *m_tessControlShaderModule;
53 break;
54
55 case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT):
56 DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL);
57 m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
58 module = *m_tessEvaluationShaderModule;
59 break;
60
61 case (VK_SHADER_STAGE_GEOMETRY_BIT):
62 DE_ASSERT(m_geometryShaderModule.get() == DE_NULL);
63 m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
64 module = *m_geometryShaderModule;
65 break;
66
67 case (VK_SHADER_STAGE_FRAGMENT_BIT):
68 DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL);
69 m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
70 module = *m_fragmentShaderModule;
71 break;
72
73 default:
74 DE_FATAL("Invalid shader stage");
75 return *this;
76 }
77
78 const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
79 {
80 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
81 DE_NULL, // const void* pNext;
82 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
83 stage, // VkShaderStageFlagBits stage;
84 module, // VkShaderModule module;
85 "main", // const char* pName;
86 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
87 };
88
89 m_shaderStageFlags |= stage;
90 m_shaderStages.push_back(pipelineShaderStageInfo);
91
92 return *this;
93 }
94
build(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkRenderPass renderPass)95 Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface& vk,
96 const VkDevice device,
97 const VkPipelineLayout pipelineLayout,
98 const VkRenderPass renderPass)
99 {
100 const VkVertexInputBindingDescription vertexInputBindingDescription =
101 {
102 0u, // uint32_t binding;
103 sizeof(tcu::Vec4), // uint32_t stride; // Vertex is a 4-element vector XYZW, position only
104 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
105 };
106
107 const VkVertexInputAttributeDescription vertexInputAttributeDescription =
108 {
109 0u, // uint32_t location;
110 0u, // uint32_t binding;
111 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
112 0u, // uint32_t offset;
113 };
114
115 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
116 {
117 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
118 DE_NULL, // const void* pNext;
119 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
120 1u, // uint32_t vertexBindingDescriptionCount;
121 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
122 1u, // uint32_t vertexAttributeDescriptionCount;
123 &vertexInputAttributeDescription, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
124 };
125
126 const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
127 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
128 {
129 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
130 DE_NULL, // const void* pNext;
131 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
132 topology, // VkPrimitiveTopology topology;
133 VK_FALSE, // VkBool32 primitiveRestartEnable;
134 };
135
136 const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
137 {
138 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
139 DE_NULL, // const void* pNext;
140 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags;
141 3u, // uint32_t patchControlPoints;
142 };
143
144 const VkViewport viewport = makeViewport(m_renderSize);
145 const VkRect2D scissor = makeRect2D(m_renderSize);
146
147 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
148 {
149 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
150 DE_NULL, // const void* pNext;
151 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
152 1u, // uint32_t viewportCount;
153 &viewport, // const VkViewport* pViewports;
154 1u, // uint32_t scissorCount;
155 &scissor, // const VkRect2D* pScissors;
156 };
157
158 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
159 {
160 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
161 DE_NULL, // const void* pNext;
162 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
163 VK_FALSE, // VkBool32 depthClampEnable;
164 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
165 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
166 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
167 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
168 VK_FALSE, // VkBool32 depthBiasEnable;
169 0.0f, // float depthBiasConstantFactor;
170 0.0f, // float depthBiasClamp;
171 0.0f, // float depthBiasSlopeFactor;
172 1.0f, // float lineWidth;
173 };
174
175 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
176 {
177 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
178 DE_NULL, // const void* pNext;
179 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
180 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
181 VK_FALSE, // VkBool32 sampleShadingEnable;
182 0.0f, // float minSampleShading;
183 DE_NULL, // const VkSampleMask* pSampleMask;
184 VK_FALSE, // VkBool32 alphaToCoverageEnable;
185 VK_FALSE // VkBool32 alphaToOneEnable;
186 };
187
188 const VkStencilOpState stencilOpStateBasic = makeStencilOpState(
189 VK_STENCIL_OP_KEEP, // stencil fail
190 VK_STENCIL_OP_KEEP, // depth & stencil pass
191 VK_STENCIL_OP_KEEP, // depth only fail
192 VK_COMPARE_OP_NEVER, // compare op
193 0u, // compare mask
194 0u, // write mask
195 0u); // reference
196
197 VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
198 {
199 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
200 DE_NULL, // const void* pNext;
201 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
202 VK_FALSE, // VkBool32 depthTestEnable;
203 VK_FALSE, // VkBool32 depthWriteEnable;
204 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
205 VK_FALSE, // VkBool32 depthBoundsTestEnable;
206 VK_FALSE, // VkBool32 stencilTestEnable;
207 stencilOpStateBasic, // VkStencilOpState front;
208 stencilOpStateBasic, // VkStencilOpState back;
209 0.0f, // float minDepthBounds;
210 1.0f, // float maxDepthBounds;
211 };
212
213 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
214 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
215 {
216 VK_FALSE, // VkBool32 blendEnable;
217 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
218 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
219 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
220 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
221 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
222 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
223 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
224 };
225
226 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
227 {
228 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
229 DE_NULL, // const void* pNext;
230 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
231 VK_FALSE, // VkBool32 logicOpEnable;
232 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
233 1u, // deUint32 attachmentCount;
234 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
235 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
236 };
237
238 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
239 {
240 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
241 DE_NULL, // const void* pNext;
242 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
243 static_cast<deUint32>(m_shaderStages.size()), // deUint32 stageCount;
244 &m_shaderStages[0], // const VkPipelineShaderStageCreateInfo* pStages;
245 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
246 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
247 (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo* pTessellationState;
248 &pipelineViewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
249 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
250 &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
251 &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
252 &pipelineColorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
253 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
254 pipelineLayout, // VkPipelineLayout layout;
255 renderPass, // VkRenderPass renderPass;
256 0u, // deUint32 subpass;
257 DE_NULL, // VkPipeline basePipelineHandle;
258 0, // deInt32 basePipelineIndex;
259 };
260
261 return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
262 }
263
makeImageCreateInfo(const tcu::IVec2 & size,const VkFormat format,const VkImageUsageFlags usage)264 VkImageCreateInfo makeImageCreateInfo (const tcu::IVec2& size, const VkFormat format, const VkImageUsageFlags usage)
265 {
266 const VkImageCreateInfo imageInfo =
267 {
268 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
269 DE_NULL, // const void* pNext;
270 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
271 VK_IMAGE_TYPE_2D, // VkImageType imageType;
272 format, // VkFormat format;
273 makeExtent3D(size.x(), size.y(), 1), // VkExtent3D extent;
274 1u, // uint32_t mipLevels;
275 1u, // uint32_t arrayLayers;
276 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
277 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
278 usage, // VkImageUsageFlags usage;
279 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
280 0u, // uint32_t queueFamilyIndexCount;
281 DE_NULL, // const uint32_t* pQueueFamilyIndices;
282 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
283 };
284 return imageInfo;
285 }
286
requireFeatures(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const FeatureFlags flags)287 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
288 {
289 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
290
291 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
292 throw tcu::NotSupportedError("Tessellation shader not supported");
293
294 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
295 throw tcu::NotSupportedError("Geometry shader not supported");
296
297 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
298 throw tcu::NotSupportedError("Double-precision floats not supported");
299
300 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
301 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
302
303 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
304 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
305 }
306
307 } // pipeline
308 } // vkt
309