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 Synchronization tests utilities
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktSynchronizationUtil.hpp"
25 #include "vkTypeUtil.hpp"
26 #include "vkCmdUtil.hpp"
27 #include "deStringUtil.hpp"
28
29 namespace vkt
30 {
31 namespace synchronization
32 {
33 using namespace vk;
34
makeBufferCreateInfo(const VkDeviceSize bufferSize,const VkBufferUsageFlags usage)35 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize bufferSize,
36 const VkBufferUsageFlags usage)
37 {
38 const VkBufferCreateInfo bufferCreateInfo =
39 {
40 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
41 DE_NULL, // const void* pNext;
42 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags;
43 bufferSize, // VkDeviceSize size;
44 usage, // VkBufferUsageFlags usage;
45 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
46 0u, // deUint32 queueFamilyIndexCount;
47 DE_NULL, // const deUint32* pQueueFamilyIndices;
48 };
49 return bufferCreateInfo;
50 }
51
makeCommandBuffer(const DeviceInterface & vk,const VkDevice device,const VkCommandPool commandPool)52 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
53 {
54 const VkCommandBufferAllocateInfo info =
55 {
56 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
57 DE_NULL, // const void* pNext;
58 commandPool, // VkCommandPool commandPool;
59 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
60 1u, // deUint32 commandBufferCount;
61 };
62 return allocateCommandBuffer(vk, device, &info);
63 }
64
makeDescriptorSet(const DeviceInterface & vk,const VkDevice device,const VkDescriptorPool descriptorPool,const VkDescriptorSetLayout setLayout)65 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface& vk,
66 const VkDevice device,
67 const VkDescriptorPool descriptorPool,
68 const VkDescriptorSetLayout setLayout)
69 {
70 const VkDescriptorSetAllocateInfo info =
71 {
72 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
73 DE_NULL, // const void* pNext;
74 descriptorPool, // VkDescriptorPool descriptorPool;
75 1u, // deUint32 descriptorSetCount;
76 &setLayout, // const VkDescriptorSetLayout* pSetLayouts;
77 };
78 return allocateDescriptorSet(vk, device, &info);
79 }
80
makePipelineLayout(const DeviceInterface & vk,const VkDevice device,const VkDescriptorSetLayout descriptorSetLayout)81 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk,
82 const VkDevice device,
83 const VkDescriptorSetLayout descriptorSetLayout)
84 {
85 const VkPipelineLayoutCreateInfo info =
86 {
87 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
88 DE_NULL, // const void* pNext;
89 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
90 1u, // deUint32 setLayoutCount;
91 &descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
92 0u, // deUint32 pushConstantRangeCount;
93 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
94 };
95 return createPipelineLayout(vk, device, &info);
96 }
97
makePipelineLayoutWithoutDescriptors(const DeviceInterface & vk,const VkDevice device)98 Move<VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const DeviceInterface& vk,
99 const VkDevice device)
100 {
101 const VkPipelineLayoutCreateInfo info =
102 {
103 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
104 DE_NULL, // const void* pNext;
105 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
106 0u, // deUint32 setLayoutCount;
107 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
108 0u, // deUint32 pushConstantRangeCount;
109 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
110 };
111 return createPipelineLayout(vk, device, &info);
112 }
113
makeComputePipeline(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkShaderModule shaderModule,const VkSpecializationInfo * specInfo,PipelineCacheData & pipelineCacheData)114 Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk,
115 const VkDevice device,
116 const VkPipelineLayout pipelineLayout,
117 const VkShaderModule shaderModule,
118 const VkSpecializationInfo* specInfo,
119 PipelineCacheData& pipelineCacheData)
120 {
121 const VkPipelineShaderStageCreateInfo shaderStageInfo =
122 {
123 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
124 DE_NULL, // const void* pNext;
125 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
126 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
127 shaderModule, // VkShaderModule module;
128 "main", // const char* pName;
129 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
130 };
131 const VkComputePipelineCreateInfo pipelineInfo =
132 {
133 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
134 DE_NULL, // const void* pNext;
135 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
136 shaderStageInfo, // VkPipelineShaderStageCreateInfo stage;
137 pipelineLayout, // VkPipelineLayout layout;
138 DE_NULL, // VkPipeline basePipelineHandle;
139 0, // deInt32 basePipelineIndex;
140 };
141
142 {
143 const vk::Unique<vk::VkPipelineCache> pipelineCache (pipelineCacheData.createPipelineCache(vk, device));
144 vk::Move<vk::VkPipeline> pipeline (createComputePipeline(vk, device, *pipelineCache, &pipelineInfo));
145
146 // Refresh data from cache
147 pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
148
149 return pipeline;
150 }
151 }
152
makeImageCreateInfo(const VkImageType imageType,const VkExtent3D & extent,const VkFormat format,const VkImageUsageFlags usage)153 VkImageCreateInfo makeImageCreateInfo (const VkImageType imageType, const VkExtent3D& extent, const VkFormat format, const VkImageUsageFlags usage)
154 {
155 const VkImageCreateInfo imageInfo =
156 {
157 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
158 DE_NULL, // const void* pNext;
159 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
160 imageType, // VkImageType imageType;
161 format, // VkFormat format;
162 extent, // VkExtent3D extent;
163 1u, // uint32_t mipLevels;
164 1u, // uint32_t arrayLayers;
165 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
166 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
167 usage, // VkImageUsageFlags usage;
168 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
169 0u, // uint32_t queueFamilyIndexCount;
170 DE_NULL, // const uint32_t* pQueueFamilyIndices;
171 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
172 };
173 return imageInfo;
174 }
175
makeImageView(const DeviceInterface & vk,const VkDevice device,const VkImage image,const VkImageViewType viewType,const VkFormat format,const VkImageSubresourceRange subresourceRange)176 Move<VkImageView> makeImageView (const DeviceInterface& vk,
177 const VkDevice device,
178 const VkImage image,
179 const VkImageViewType viewType,
180 const VkFormat format,
181 const VkImageSubresourceRange subresourceRange)
182 {
183 const VkImageViewCreateInfo imageViewParams =
184 {
185 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
186 DE_NULL, // const void* pNext;
187 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags;
188 image, // VkImage image;
189 viewType, // VkImageViewType viewType;
190 format, // VkFormat format;
191 makeComponentMappingRGBA(), // VkComponentMapping components;
192 subresourceRange, // VkImageSubresourceRange subresourceRange;
193 };
194 return createImageView(vk, device, &imageViewParams);
195 }
196
makeBufferImageCopy(const VkImageSubresourceLayers subresourceLayers,const VkExtent3D extent)197 VkBufferImageCopy makeBufferImageCopy (const VkImageSubresourceLayers subresourceLayers,
198 const VkExtent3D extent)
199 {
200 const VkBufferImageCopy copyParams =
201 {
202 0ull, // VkDeviceSize bufferOffset;
203 0u, // deUint32 bufferRowLength;
204 0u, // deUint32 bufferImageHeight;
205 subresourceLayers, // VkImageSubresourceLayers imageSubresource;
206 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
207 extent, // VkExtent3D imageExtent;
208 };
209 return copyParams;
210 }
211
beginRenderPassWithRasterizationDisabled(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRenderPass renderPass,const VkFramebuffer framebuffer)212 void beginRenderPassWithRasterizationDisabled (const DeviceInterface& vk,
213 const VkCommandBuffer commandBuffer,
214 const VkRenderPass renderPass,
215 const VkFramebuffer framebuffer)
216 {
217 const VkRect2D renderArea = {{ 0, 0 }, { 0, 0 }};
218
219 beginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea);
220 }
221
makeFramebuffer(const DeviceInterface & vk,const VkDevice device,const VkRenderPass renderPass,const VkImageView colorAttachment,const deUint32 width,const deUint32 height,const deUint32 layers)222 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface& vk,
223 const VkDevice device,
224 const VkRenderPass renderPass,
225 const VkImageView colorAttachment,
226 const deUint32 width,
227 const deUint32 height,
228 const deUint32 layers)
229 {
230 const VkFramebufferCreateInfo framebufferInfo = {
231 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
232 DE_NULL, // const void* pNext;
233 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags;
234 renderPass, // VkRenderPass renderPass;
235 1u, // uint32_t attachmentCount;
236 &colorAttachment, // const VkImageView* pAttachments;
237 width, // uint32_t width;
238 height, // uint32_t height;
239 layers, // uint32_t layers;
240 };
241
242 return createFramebuffer(vk, device, &framebufferInfo);
243 }
244
setShader(const DeviceInterface & vk,const VkDevice device,const VkShaderStageFlagBits stage,const ProgramBinary & binary,const VkSpecializationInfo * specInfo)245 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface& vk,
246 const VkDevice device,
247 const VkShaderStageFlagBits stage,
248 const ProgramBinary& binary,
249 const VkSpecializationInfo* specInfo)
250 {
251 VkShaderModule module;
252 switch (stage)
253 {
254 case (VK_SHADER_STAGE_VERTEX_BIT):
255 DE_ASSERT(m_vertexShaderModule.get() == DE_NULL);
256 m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
257 module = *m_vertexShaderModule;
258 break;
259
260 case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT):
261 DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL);
262 m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
263 module = *m_tessControlShaderModule;
264 break;
265
266 case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT):
267 DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL);
268 m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
269 module = *m_tessEvaluationShaderModule;
270 break;
271
272 case (VK_SHADER_STAGE_GEOMETRY_BIT):
273 DE_ASSERT(m_geometryShaderModule.get() == DE_NULL);
274 m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
275 module = *m_geometryShaderModule;
276 break;
277
278 case (VK_SHADER_STAGE_FRAGMENT_BIT):
279 DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL);
280 m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
281 module = *m_fragmentShaderModule;
282 break;
283
284 default:
285 DE_FATAL("Invalid shader stage");
286 return *this;
287 }
288
289 const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
290 {
291 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
292 DE_NULL, // const void* pNext;
293 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
294 stage, // VkShaderStageFlagBits stage;
295 module, // VkShaderModule module;
296 "main", // const char* pName;
297 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
298 };
299
300 m_shaderStageFlags |= stage;
301 m_shaderStages.push_back(pipelineShaderStageInfo);
302
303 return *this;
304 }
305
setVertexInputSingleAttribute(const VkFormat vertexFormat,const deUint32 stride)306 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setVertexInputSingleAttribute (const VkFormat vertexFormat, const deUint32 stride)
307 {
308 const VkVertexInputBindingDescription bindingDesc =
309 {
310 0u, // uint32_t binding;
311 stride, // uint32_t stride;
312 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
313 };
314 const VkVertexInputAttributeDescription attributeDesc =
315 {
316 0u, // uint32_t location;
317 0u, // uint32_t binding;
318 vertexFormat, // VkFormat format;
319 0u, // uint32_t offset;
320 };
321
322 m_vertexInputBindings.clear();
323 m_vertexInputBindings.push_back(bindingDesc);
324
325 m_vertexInputAttributes.clear();
326 m_vertexInputAttributes.push_back(attributeDesc);
327
328 return *this;
329 }
330
331 template<typename T>
dataPointer(const std::vector<T> & vec)332 inline const T* dataPointer (const std::vector<T>& vec)
333 {
334 return (vec.size() != 0 ? &vec[0] : DE_NULL);
335 }
336
build(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkRenderPass renderPass,PipelineCacheData & pipelineCacheData)337 Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface& vk,
338 const VkDevice device,
339 const VkPipelineLayout pipelineLayout,
340 const VkRenderPass renderPass,
341 PipelineCacheData& pipelineCacheData)
342 {
343 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
344 {
345 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
346 DE_NULL, // const void* pNext;
347 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
348 static_cast<deUint32>(m_vertexInputBindings.size()), // uint32_t vertexBindingDescriptionCount;
349 dataPointer(m_vertexInputBindings), // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
350 static_cast<deUint32>(m_vertexInputAttributes.size()), // uint32_t vertexAttributeDescriptionCount;
351 dataPointer(m_vertexInputAttributes), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
352 };
353
354 const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
355 : m_primitiveTopology;
356 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
357 {
358 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
359 DE_NULL, // const void* pNext;
360 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
361 topology, // VkPrimitiveTopology topology;
362 VK_FALSE, // VkBool32 primitiveRestartEnable;
363 };
364
365 const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
366 {
367 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
368 DE_NULL, // const void* pNext;
369 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags;
370 m_patchControlPoints, // uint32_t patchControlPoints;
371 };
372
373 const VkViewport viewport = makeViewport(m_renderSize);
374 const VkRect2D scissor = makeRect2D(m_renderSize);
375
376 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
377 {
378 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
379 DE_NULL, // const void* pNext;
380 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
381 1u, // uint32_t viewportCount;
382 &viewport, // const VkViewport* pViewports;
383 1u, // uint32_t scissorCount;
384 &scissor, // const VkRect2D* pScissors;
385 };
386
387 const bool isRasterizationDisabled = ((m_shaderStageFlags & VK_SHADER_STAGE_FRAGMENT_BIT) == 0);
388 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
389 {
390 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
391 DE_NULL, // const void* pNext;
392 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
393 VK_FALSE, // VkBool32 depthClampEnable;
394 isRasterizationDisabled, // VkBool32 rasterizerDiscardEnable;
395 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
396 m_cullModeFlags, // VkCullModeFlags cullMode;
397 m_frontFace, // VkFrontFace frontFace;
398 VK_FALSE, // VkBool32 depthBiasEnable;
399 0.0f, // float depthBiasConstantFactor;
400 0.0f, // float depthBiasClamp;
401 0.0f, // float depthBiasSlopeFactor;
402 1.0f, // float lineWidth;
403 };
404
405 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
406 {
407 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
408 DE_NULL, // const void* pNext;
409 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
410 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
411 VK_FALSE, // VkBool32 sampleShadingEnable;
412 0.0f, // float minSampleShading;
413 DE_NULL, // const VkSampleMask* pSampleMask;
414 VK_FALSE, // VkBool32 alphaToCoverageEnable;
415 VK_FALSE // VkBool32 alphaToOneEnable;
416 };
417
418 const VkStencilOpState stencilOpState = makeStencilOpState(
419 VK_STENCIL_OP_KEEP, // stencil fail
420 VK_STENCIL_OP_KEEP, // depth & stencil pass
421 VK_STENCIL_OP_KEEP, // depth only fail
422 VK_COMPARE_OP_NEVER, // compare op
423 0u, // compare mask
424 0u, // write mask
425 0u); // reference
426
427 const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
428 {
429 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
430 DE_NULL, // const void* pNext;
431 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
432 VK_FALSE, // VkBool32 depthTestEnable;
433 VK_FALSE, // VkBool32 depthWriteEnable;
434 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
435 VK_FALSE, // VkBool32 depthBoundsTestEnable;
436 VK_FALSE, // VkBool32 stencilTestEnable;
437 stencilOpState, // VkStencilOpState front;
438 stencilOpState, // VkStencilOpState back;
439 0.0f, // float minDepthBounds;
440 1.0f, // float maxDepthBounds;
441 };
442
443 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
444 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
445 {
446 m_blendEnable, // VkBool32 blendEnable;
447 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor;
448 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor;
449 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
450 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor;
451 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor;
452 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
453 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
454 };
455
456 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
457 {
458 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
459 DE_NULL, // const void* pNext;
460 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
461 VK_FALSE, // VkBool32 logicOpEnable;
462 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
463 1u, // deUint32 attachmentCount;
464 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
465 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
466 };
467
468 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
469 {
470 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
471 DE_NULL, // const void* pNext;
472 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
473 static_cast<deUint32>(m_shaderStages.size()), // deUint32 stageCount;
474 &m_shaderStages[0], // const VkPipelineShaderStageCreateInfo* pStages;
475 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
476 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
477 (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo* pTessellationState;
478 (isRasterizationDisabled ? DE_NULL : &pipelineViewportStateInfo), // const VkPipelineViewportStateCreateInfo* pViewportState;
479 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
480 (isRasterizationDisabled ? DE_NULL : &pipelineMultisampleStateInfo), // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
481 (isRasterizationDisabled ? DE_NULL : &pipelineDepthStencilStateInfo), // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
482 (isRasterizationDisabled ? DE_NULL : &pipelineColorBlendStateInfo), // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
483 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
484 pipelineLayout, // VkPipelineLayout layout;
485 renderPass, // VkRenderPass renderPass;
486 0u, // deUint32 subpass;
487 DE_NULL, // VkPipeline basePipelineHandle;
488 0, // deInt32 basePipelineIndex;
489 };
490
491 {
492 const vk::Unique<vk::VkPipelineCache> pipelineCache (pipelineCacheData.createPipelineCache(vk, device));
493 vk::Move<vk::VkPipeline> pipeline (createGraphicsPipeline(vk, device, *pipelineCache, &graphicsPipelineInfo));
494
495 // Refresh data from cache
496 pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
497
498 return pipeline;
499 }
500 }
501
requireFeatures(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const FeatureFlags flags)502 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
503 {
504 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
505
506 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
507 throw tcu::NotSupportedError("Tessellation shader not supported");
508
509 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
510 throw tcu::NotSupportedError("Geometry shader not supported");
511
512 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
513 throw tcu::NotSupportedError("Double-precision floats not supported");
514
515 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
516 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
517
518 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
519 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
520
521 if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
522 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
523
524 if (((flags & FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS) != 0) && !features.shaderStorageImageExtendedFormats)
525 throw tcu::NotSupportedError("Storage image extended formats not supported");
526 }
527
getResourceName(const ResourceDescription & resource)528 std::string getResourceName (const ResourceDescription& resource)
529 {
530 std::ostringstream str;
531
532 if (resource.type == RESOURCE_TYPE_BUFFER)
533 str << "buffer_" << resource.size.x();
534 else if (resource.type == RESOURCE_TYPE_IMAGE)
535 {
536 str << "image_" << resource.size.x()
537 << (resource.size.y() > 0 ? "x" + de::toString(resource.size.y()) : "")
538 << (resource.size.z() > 0 ? "x" + de::toString(resource.size.z()) : "")
539 << "_" << de::toLower(getFormatName(resource.imageFormat)).substr(10);
540 }
541 else if (isIndirectBuffer(resource.type))
542 str << "indirect_buffer";
543 else
544 DE_ASSERT(0);
545
546 return str.str();
547 }
548
isIndirectBuffer(const ResourceType type)549 bool isIndirectBuffer (const ResourceType type)
550 {
551 switch (type)
552 {
553 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW:
554 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED:
555 case RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH:
556 return true;
557
558 default:
559 return false;
560 }
561 }
562
PipelineCacheData(void)563 PipelineCacheData::PipelineCacheData (void)
564 {
565 }
566
~PipelineCacheData(void)567 PipelineCacheData::~PipelineCacheData (void)
568 {
569 }
570
createPipelineCache(const vk::DeviceInterface & vk,const vk::VkDevice device) const571 vk::Move<VkPipelineCache> PipelineCacheData::createPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device) const
572 {
573 const de::ScopedLock dataLock (m_lock);
574 const struct vk::VkPipelineCacheCreateInfo params =
575 {
576 vk::VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
577 DE_NULL,
578 (vk::VkPipelineCacheCreateFlags)0,
579 (deUintptr)m_data.size(),
580 (m_data.empty() ? DE_NULL : &m_data[0])
581 };
582
583 return vk::createPipelineCache(vk, device, ¶ms);
584 }
585
setFromPipelineCache(const vk::DeviceInterface & vk,const vk::VkDevice device,const vk::VkPipelineCache pipelineCache)586 void PipelineCacheData::setFromPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineCache pipelineCache)
587 {
588 const de::ScopedLock dataLock (m_lock);
589 deUintptr dataSize = 0;
590
591 VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, DE_NULL));
592
593 m_data.resize(dataSize);
594
595 if (dataSize > 0)
596 VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, &m_data[0]));
597 }
598
599 } // synchronization
600 } // vkt
601