1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2016 The Android Open Source Project
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 * \brief Vulkan ShaderExecutor
24 *//*--------------------------------------------------------------------*/
26 #include "vktShaderExecutor.hpp"
28 #include "vkMemUtil.hpp"
30 #include "vkPrograms.hpp"
31 #include "vkRefUtil.hpp"
32 #include "vkTypeUtil.hpp"
33 #include "vkQueryUtil.hpp"
34 #include "vkBuilderUtil.hpp"
36 #include "gluShaderUtil.hpp"
38 #include "tcuVector.hpp"
39 #include "tcuTestLog.hpp"
40 #include "tcuTextureUtil.hpp"
42 #include "deUniquePtr.hpp"
43 #include "deStringUtil.hpp"
44 #include "deSharedPtr.hpp"
55 namespace shaderexecutor
62 DEFAULT_RENDER_WIDTH = 100,
63 DEFAULT_RENDER_HEIGHT = 100,
68 typedef de::SharedPtr<Unique<VkImage> > VkImageSp;
69 typedef de::SharedPtr<Unique<VkImageView> > VkImageViewSp;
70 typedef de::SharedPtr<Unique<VkBuffer> > VkBufferSp;
71 typedef de::SharedPtr<Allocation> AllocationSp;
75 static VkClearValue getDefaultClearColor (void)
77 return makeClearValueColorF32(0.125f, 0.25f, 0.5f, 1.0f);
80 static std::string generateEmptyFragmentSource (void)
82 std::ostringstream src;
84 src << "#version 310 es\n"
85 "layout(location=0) out highp vec4 o_color;\n";
87 src << "void main (void)\n{\n";
88 src << " o_color = vec4(0.0);\n";
94 static std::string generatePassthroughVertexShader (const std::vector<Symbol>& inputs, const char* inputPrefix, const char* outputPrefix)
97 std::ostringstream src;
100 src << "#version 310 es\n"
101 "layout(location = " << location << ") in highp vec4 a_position;\n";
103 for (vector<Symbol>::const_iterator input = inputs.begin(); input != inputs.end(); ++input)
106 src << "layout(location = "<< location << ") in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n"
107 << "layout(location = " << location - 1 << ") flat out " << glu::declare(input->varType, outputPrefix + input->name) << ";\n";
110 src << "\nvoid main (void)\n{\n"
111 << " gl_Position = a_position;\n"
112 << " gl_PointSize = 1.0;\n";
114 for (vector<Symbol>::const_iterator input = inputs.begin(); input != inputs.end(); ++input)
115 src << "\t" << outputPrefix << input->name << " = " << inputPrefix << input->name << ";\n";
122 static std::string generateVertexShader (const ShaderSpec& shaderSpec, const std::string& inputPrefix, const std::string& outputPrefix)
124 DE_ASSERT(!inputPrefix.empty() && !outputPrefix.empty());
126 std::ostringstream src;
128 src << "#version 310 es\n";
130 if (!shaderSpec.globalDeclarations.empty())
131 src << shaderSpec.globalDeclarations << "\n";
133 src << "layout(location = 0) in highp vec4 a_position;\n";
135 int locationNumber = 1;
136 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber)
137 src << "layout(location = " << locationNumber << ") in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n";
140 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber)
142 DE_ASSERT(output->varType.isBasicType());
144 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
146 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
147 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
148 const glu::VarType intType (intBaseType, glu::PRECISION_HIGHP);
150 src << "layout(location = " << locationNumber << ") flat out " << glu::declare(intType, outputPrefix + output->name) << ";\n";
153 src << "layout(location = " << locationNumber << ") flat out " << glu::declare(output->varType, outputPrefix + output->name) << ";\n";
157 << "void main (void)\n"
159 << " gl_Position = a_position;\n"
160 << " gl_PointSize = 1.0;\n";
162 // Declare & fetch local input variables
163 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input)
164 src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << ";\n";
166 // Declare local output variables
167 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
168 src << "\t" << glu::declare(output->varType, output->name) << ";\n";
170 // Operation - indented to correct level.
172 std::istringstream opSrc (shaderSpec.source);
175 while (std::getline(opSrc, line))
176 src << "\t" << line << "\n";
179 // Assignments to outputs.
180 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
182 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
184 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
185 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
187 src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << output->name << ");\n";
190 src << "\t" << outputPrefix << output->name << " = " << output->name << ";\n";
198 struct FragmentOutputLayout
200 std::vector<const Symbol*> locationSymbols; //! Symbols by location
201 std::map<std::string, int> locationMap; //! Map from symbol name to start location
204 static void generateFragShaderOutputDecl (std::ostream& src, const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& outputPrefix)
206 for (int outNdx = 0; outNdx < (int)shaderSpec.outputs.size(); ++outNdx)
208 const Symbol& output = shaderSpec.outputs[outNdx];
209 const int location = de::lookup(outLocationMap, output.name);
210 const std::string outVarName = outputPrefix + output.name;
211 glu::VariableDeclaration decl (output.varType, outVarName, glu::STORAGE_OUT, glu::INTERPOLATION_LAST, glu::Layout(location));
213 TCU_CHECK_INTERNAL(output.varType.isBasicType());
215 if (useIntOutputs && glu::isDataTypeFloatOrVec(output.varType.getBasicType()))
217 const int vecSize = glu::getDataTypeScalarSize(output.varType.getBasicType());
218 const glu::DataType uintBasicType = vecSize > 1 ? glu::getDataTypeUintVec(vecSize) : glu::TYPE_UINT;
219 const glu::VarType uintType (uintBasicType, glu::PRECISION_HIGHP);
221 decl.varType = uintType;
222 src << decl << ";\n";
224 else if (glu::isDataTypeBoolOrBVec(output.varType.getBasicType()))
226 const int vecSize = glu::getDataTypeScalarSize(output.varType.getBasicType());
227 const glu::DataType intBasicType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
228 const glu::VarType intType (intBasicType, glu::PRECISION_HIGHP);
230 decl.varType = intType;
231 src << decl << ";\n";
233 else if (glu::isDataTypeMatrix(output.varType.getBasicType()))
235 const int vecSize = glu::getDataTypeMatrixNumRows(output.varType.getBasicType());
236 const int numVecs = glu::getDataTypeMatrixNumColumns(output.varType.getBasicType());
237 const glu::DataType uintBasicType = glu::getDataTypeUintVec(vecSize);
238 const glu::VarType uintType (uintBasicType, glu::PRECISION_HIGHP);
240 decl.varType = uintType;
241 for (int vecNdx = 0; vecNdx < numVecs; ++vecNdx)
243 decl.name = outVarName + "_" + de::toString(vecNdx);
244 decl.layout.location = location + vecNdx;
245 src << decl << ";\n";
249 src << decl << ";\n";
253 static void generateFragShaderOutAssign (std::ostream& src, const ShaderSpec& shaderSpec, bool useIntOutputs, const std::string& valuePrefix, const std::string& outputPrefix)
255 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
257 if (useIntOutputs && glu::isDataTypeFloatOrVec(output->varType.getBasicType()))
258 src << " o_" << output->name << " = floatBitsToUint(" << valuePrefix << output->name << ");\n";
259 else if (glu::isDataTypeMatrix(output->varType.getBasicType()))
261 const int numVecs = glu::getDataTypeMatrixNumColumns(output->varType.getBasicType());
263 for (int vecNdx = 0; vecNdx < numVecs; ++vecNdx)
265 src << "\t" << outputPrefix << output->name << "_" << vecNdx << " = floatBitsToUint(" << valuePrefix << output->name << "[" << vecNdx << "]);\n";
267 src << "\t" << outputPrefix << output->name << "_" << vecNdx << " = " << valuePrefix << output->name << "[" << vecNdx << "];\n";
269 else if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
271 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
272 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
274 src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << valuePrefix << output->name << ");\n";
277 src << "\t" << outputPrefix << output->name << " = " << valuePrefix << output->name << ";\n";
281 static std::string generatePassthroughFragmentShader (const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& inputPrefix, const std::string& outputPrefix)
283 std::ostringstream src;
285 src << "#version 310 es\n";
287 if (!shaderSpec.globalDeclarations.empty())
288 src << shaderSpec.globalDeclarations << "\n";
290 int locationNumber = 0;
291 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber)
293 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
295 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
296 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
297 const glu::VarType intType (intBaseType, glu::PRECISION_HIGHP);
299 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(intType, inputPrefix + output->name) << ";\n";
302 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(output->varType, inputPrefix + output->name) << ";\n";
305 generateFragShaderOutputDecl(src, shaderSpec, useIntOutputs, outLocationMap, outputPrefix);
307 src << "\nvoid main (void)\n{\n";
309 generateFragShaderOutAssign(src, shaderSpec, useIntOutputs, inputPrefix, outputPrefix);
316 static std::string generateGeometryShader (const ShaderSpec& shaderSpec, const std::string& inputPrefix, const std::string& outputPrefix)
318 DE_ASSERT(!inputPrefix.empty() && !outputPrefix.empty());
320 std::ostringstream src;
322 src << "#version 310 es\n"
323 "#extension GL_EXT_geometry_shader : require\n";
325 if (!shaderSpec.globalDeclarations.empty())
326 src << shaderSpec.globalDeclarations << "\n";
328 src << "layout(points) in;\n"
329 << "layout(points, max_vertices = 1) out;\n";
331 int locationNumber = 0;
332 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber)
333 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(input->varType, inputPrefix + input->name) << "[];\n";
336 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber)
338 DE_ASSERT(output->varType.isBasicType());
340 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
342 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
343 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
344 const glu::VarType intType (intBaseType, glu::PRECISION_HIGHP);
346 src << "layout(location = " << locationNumber << ") flat out " << glu::declare(intType, outputPrefix + output->name) << ";\n";
349 src << "layout(location = " << locationNumber << ") flat out " << glu::declare(output->varType, outputPrefix + output->name) << ";\n";
353 << "void main (void)\n"
355 << " gl_Position = gl_in[0].gl_Position;\n\n";
357 // Fetch input variables
358 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input)
359 src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << "[0];\n";
361 // Declare local output variables.
362 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
363 src << "\t" << glu::declare(output->varType, output->name) << ";\n";
367 // Operation - indented to correct level.
369 std::istringstream opSrc (shaderSpec.source);
372 while (std::getline(opSrc, line))
373 src << "\t" << line << "\n";
376 // Assignments to outputs.
377 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
379 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
381 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
382 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
384 src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << output->name << ");\n";
387 src << "\t" << outputPrefix << output->name << " = " << output->name << ";\n";
390 src << " EmitVertex();\n"
391 << " EndPrimitive();\n"
397 static std::string generateFragmentShader (const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& inputPrefix, const std::string& outputPrefix)
399 std::ostringstream src;
400 src << "#version 310 es\n";
401 if (!shaderSpec.globalDeclarations.empty())
402 src << shaderSpec.globalDeclarations << "\n";
404 int locationNumber = 0;
405 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber)
406 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n";
408 generateFragShaderOutputDecl(src, shaderSpec, useIntOutputs, outLocationMap, outputPrefix);
410 src << "\nvoid main (void)\n{\n";
412 // Declare & fetch local input variables
413 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input)
414 src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << ";\n";
416 // Declare output variables
417 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
418 src << "\t" << glu::declare(output->varType, output->name) << ";\n";
420 // Operation - indented to correct level.
422 std::istringstream opSrc (shaderSpec.source);
425 while (std::getline(opSrc, line))
426 src << "\t" << line << "\n";
429 generateFragShaderOutAssign(src, shaderSpec, useIntOutputs, "", outputPrefix);
436 // FragmentOutExecutor
438 class FragmentOutExecutor : public ShaderExecutor
441 FragmentOutExecutor (Context& context, glu::ShaderType shaderType, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
442 virtual ~FragmentOutExecutor (void);
444 virtual void execute (int numValues,
445 const void* const* inputs,
446 void* const* outputs,
447 VkDescriptorSet extraResources);
450 const glu::ShaderType m_shaderType;
451 const FragmentOutputLayout m_outputLayout;
454 void bindAttributes (int numValues,
455 const void* const* inputs);
457 void addAttribute (deUint32 bindingLocation,
459 deUint32 sizePerElement,
461 const void* dataPtr);
462 // reinit render data members
463 virtual void clearRenderData (void);
465 const VkDescriptorSetLayout m_extraResourcesLayout;
467 std::vector<VkVertexInputBindingDescription> m_vertexBindingDescriptions;
468 std::vector<VkVertexInputAttributeDescription> m_vertexAttributeDescriptions;
469 std::vector<VkBufferSp> m_vertexBuffers;
470 std::vector<AllocationSp> m_vertexBufferAllocs;
473 static FragmentOutputLayout computeFragmentOutputLayout (const std::vector<Symbol>& symbols)
475 FragmentOutputLayout ret;
478 for (std::vector<Symbol>::const_iterator it = symbols.begin(); it != symbols.end(); ++it)
480 const int numLocations = glu::getDataTypeNumLocations(it->varType.getBasicType());
482 TCU_CHECK_INTERNAL(!de::contains(ret.locationMap, it->name));
483 de::insert(ret.locationMap, it->name, location);
484 location += numLocations;
486 for (int ndx = 0; ndx < numLocations; ++ndx)
487 ret.locationSymbols.push_back(&*it);
493 FragmentOutExecutor::FragmentOutExecutor (Context& context, glu::ShaderType shaderType, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
494 : ShaderExecutor (context, shaderSpec)
495 , m_shaderType (shaderType)
496 , m_outputLayout (computeFragmentOutputLayout(m_shaderSpec.outputs))
497 , m_extraResourcesLayout (extraResourcesLayout)
501 FragmentOutExecutor::~FragmentOutExecutor (void)
505 static std::vector<tcu::Vec2> computeVertexPositions (int numValues, const tcu::IVec2& renderSize)
507 std::vector<tcu::Vec2> positions(numValues);
508 for (int valNdx = 0; valNdx < numValues; valNdx++)
510 const int ix = valNdx % renderSize.x();
511 const int iy = valNdx / renderSize.x();
512 const float fx = -1.0f + 2.0f*((float(ix) + 0.5f) / float(renderSize.x()));
513 const float fy = -1.0f + 2.0f*((float(iy) + 0.5f) / float(renderSize.y()));
515 positions[valNdx] = tcu::Vec2(fx, fy);
521 static tcu::TextureFormat getRenderbufferFormatForOutput (const glu::VarType& outputType, bool useIntOutputs)
523 const tcu::TextureFormat::ChannelOrder channelOrderMap[] =
525 tcu::TextureFormat::R,
526 tcu::TextureFormat::RG,
527 tcu::TextureFormat::RGBA, // No RGB variants available.
528 tcu::TextureFormat::RGBA
531 const glu::DataType basicType = outputType.getBasicType();
532 const int numComps = glu::getDataTypeNumComponents(basicType);
533 tcu::TextureFormat::ChannelType channelType;
535 switch (glu::getDataTypeScalarType(basicType))
537 case glu::TYPE_UINT: channelType = tcu::TextureFormat::UNSIGNED_INT32; break;
538 case glu::TYPE_INT: channelType = tcu::TextureFormat::SIGNED_INT32; break;
539 case glu::TYPE_BOOL: channelType = tcu::TextureFormat::SIGNED_INT32; break;
540 case glu::TYPE_FLOAT: channelType = useIntOutputs ? tcu::TextureFormat::UNSIGNED_INT32 : tcu::TextureFormat::FLOAT; break;
542 throw tcu::InternalError("Invalid output type");
545 DE_ASSERT(de::inRange<int>(numComps, 1, DE_LENGTH_OF_ARRAY(channelOrderMap)));
547 return tcu::TextureFormat(channelOrderMap[numComps-1], channelType);
550 static VkFormat getAttributeFormat (const glu::DataType dataType)
554 case glu::TYPE_FLOAT: return VK_FORMAT_R32_SFLOAT;
555 case glu::TYPE_FLOAT_VEC2: return VK_FORMAT_R32G32_SFLOAT;
556 case glu::TYPE_FLOAT_VEC3: return VK_FORMAT_R32G32B32_SFLOAT;
557 case glu::TYPE_FLOAT_VEC4: return VK_FORMAT_R32G32B32A32_SFLOAT;
559 case glu::TYPE_INT: return VK_FORMAT_R32_SINT;
560 case glu::TYPE_INT_VEC2: return VK_FORMAT_R32G32_SINT;
561 case glu::TYPE_INT_VEC3: return VK_FORMAT_R32G32B32_SINT;
562 case glu::TYPE_INT_VEC4: return VK_FORMAT_R32G32B32A32_SINT;
564 case glu::TYPE_UINT: return VK_FORMAT_R32_UINT;
565 case glu::TYPE_UINT_VEC2: return VK_FORMAT_R32G32_UINT;
566 case glu::TYPE_UINT_VEC3: return VK_FORMAT_R32G32B32_UINT;
567 case glu::TYPE_UINT_VEC4: return VK_FORMAT_R32G32B32A32_UINT;
569 case glu::TYPE_FLOAT_MAT2: return VK_FORMAT_R32G32_SFLOAT;
570 case glu::TYPE_FLOAT_MAT2X3: return VK_FORMAT_R32G32B32_SFLOAT;
571 case glu::TYPE_FLOAT_MAT2X4: return VK_FORMAT_R32G32B32A32_SFLOAT;
572 case glu::TYPE_FLOAT_MAT3X2: return VK_FORMAT_R32G32_SFLOAT;
573 case glu::TYPE_FLOAT_MAT3: return VK_FORMAT_R32G32B32_SFLOAT;
574 case glu::TYPE_FLOAT_MAT3X4: return VK_FORMAT_R32G32B32A32_SFLOAT;
575 case glu::TYPE_FLOAT_MAT4X2: return VK_FORMAT_R32G32_SFLOAT;
576 case glu::TYPE_FLOAT_MAT4X3: return VK_FORMAT_R32G32B32_SFLOAT;
577 case glu::TYPE_FLOAT_MAT4: return VK_FORMAT_R32G32B32A32_SFLOAT;
580 return VK_FORMAT_UNDEFINED;
584 void FragmentOutExecutor::addAttribute (deUint32 bindingLocation, VkFormat format, deUint32 sizePerElement, deUint32 count, const void* dataPtr)
586 // Add binding specification
587 const deUint32 binding = (deUint32)m_vertexBindingDescriptions.size();
588 const VkVertexInputBindingDescription bindingDescription =
592 VK_VERTEX_INPUT_RATE_VERTEX
595 m_vertexBindingDescriptions.push_back(bindingDescription);
597 // Add location and format specification
598 const VkVertexInputAttributeDescription attributeDescription =
600 bindingLocation, // deUint32 location;
601 binding, // deUint32 binding;
602 format, // VkFormat format;
603 0u, // deUint32 offsetInBytes;
606 m_vertexAttributeDescriptions.push_back(attributeDescription);
608 // Upload data to buffer
609 const VkDevice vkDevice = m_context.getDevice();
610 const DeviceInterface& vk = m_context.getDeviceInterface();
611 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
613 const VkDeviceSize inputSize = sizePerElement * count;
614 const VkBufferCreateInfo vertexBufferParams =
616 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
617 DE_NULL, // const void* pNext;
618 0u, // VkBufferCreateFlags flags;
619 inputSize, // VkDeviceSize size;
620 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
621 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
622 1u, // deUint32 queueFamilyCount;
623 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
626 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &vertexBufferParams);
627 de::MovePtr<Allocation> alloc = m_context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
629 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
631 deMemcpy(alloc->getHostPtr(), dataPtr, (size_t)inputSize);
632 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), inputSize);
634 m_vertexBuffers.push_back(de::SharedPtr<Unique<VkBuffer> >(new Unique<VkBuffer>(buffer)));
635 m_vertexBufferAllocs.push_back(AllocationSp(alloc.release()));
638 void FragmentOutExecutor::bindAttributes (int numValues, const void* const* inputs)
641 for (int inputNdx = 0; inputNdx < (int)m_shaderSpec.inputs.size(); inputNdx++)
643 const Symbol& symbol = m_shaderSpec.inputs[inputNdx];
644 const void* ptr = inputs[inputNdx];
645 const glu::DataType basicType = symbol.varType.getBasicType();
646 const int vecSize = glu::getDataTypeScalarSize(basicType);
647 const VkFormat format = getAttributeFormat(basicType);
649 int numAttrsToAdd = 1;
651 if (glu::isDataTypeFloatOrVec(basicType))
652 elementSize = sizeof(float);
653 else if (glu::isDataTypeIntOrIVec(basicType))
654 elementSize = sizeof(int);
655 else if (glu::isDataTypeUintOrUVec(basicType))
656 elementSize = sizeof(deUint32);
657 else if (glu::isDataTypeMatrix(basicType))
659 int numRows = glu::getDataTypeMatrixNumRows(basicType);
660 int numCols = glu::getDataTypeMatrixNumColumns(basicType);
662 elementSize = numRows * numCols * (int)sizeof(float);
663 numAttrsToAdd = numCols;
668 // add attributes, in case of matrix every column is binded as an attribute
669 for (int attrNdx = 0; attrNdx < numAttrsToAdd; attrNdx++)
671 addAttribute((deUint32)m_vertexBindingDescriptions.size(), format, elementSize * vecSize, numValues, ptr);
676 void FragmentOutExecutor::clearRenderData (void)
678 m_vertexBindingDescriptions.clear();
679 m_vertexAttributeDescriptions.clear();
680 m_vertexBuffers.clear();
681 m_vertexBufferAllocs.clear();
684 static Move<VkDescriptorSetLayout> createEmptyDescriptorSetLayout (const DeviceInterface& vkd, VkDevice device)
686 const VkDescriptorSetLayoutCreateInfo createInfo =
688 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
690 (VkDescriptorSetLayoutCreateFlags)0,
694 return createDescriptorSetLayout(vkd, device, &createInfo);
697 static Move<VkDescriptorPool> createDummyDescriptorPool (const DeviceInterface& vkd, VkDevice device)
699 const VkDescriptorPoolSize dummySize =
701 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
704 const VkDescriptorPoolCreateInfo createInfo =
706 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
708 (VkDescriptorPoolCreateFlags)VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
713 return createDescriptorPool(vkd, device, &createInfo);
716 static Move<VkDescriptorSet> allocateSingleDescriptorSet (const DeviceInterface& vkd, VkDevice device, VkDescriptorPool pool, VkDescriptorSetLayout layout)
718 const VkDescriptorSetAllocateInfo allocInfo =
720 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
726 return allocateDescriptorSet(vkd, device, &allocInfo);
729 void FragmentOutExecutor::execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources)
731 const VkDevice vkDevice = m_context.getDevice();
732 const DeviceInterface& vk = m_context.getDeviceInterface();
733 const VkQueue queue = m_context.getUniversalQueue();
734 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
735 Allocator& memAlloc = m_context.getDefaultAllocator();
737 const deUint32 renderSizeX = de::min(static_cast<deUint32>(DEFAULT_RENDER_WIDTH), (deUint32)numValues);
738 const deUint32 renderSizeY = ((deUint32)numValues / renderSizeX) + (((deUint32)numValues % renderSizeX != 0) ? 1u : 0u);
739 const tcu::UVec2 renderSize (renderSizeX, renderSizeY);
740 std::vector<tcu::Vec2> positions;
742 const bool useGeometryShader = m_shaderType == glu::SHADERTYPE_GEOMETRY;
744 std::vector<VkImageSp> colorImages;
745 std::vector<VkImageMemoryBarrier> colorImagePreRenderBarriers;
746 std::vector<VkImageMemoryBarrier> colorImagePostRenderBarriers;
747 std::vector<AllocationSp> colorImageAllocs;
748 std::vector<VkAttachmentDescription> attachments;
749 std::vector<VkClearValue> attachmentClearValues;
750 std::vector<VkImageViewSp> colorImageViews;
752 std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentStates;
753 std::vector<VkAttachmentReference> colorAttachmentReferences;
755 Move<VkRenderPass> renderPass;
756 Move<VkFramebuffer> framebuffer;
757 Move<VkPipelineLayout> pipelineLayout;
758 Move<VkPipeline> graphicsPipeline;
760 Move<VkShaderModule> vertexShaderModule;
761 Move<VkShaderModule> geometryShaderModule;
762 Move<VkShaderModule> fragmentShaderModule;
764 Move<VkCommandPool> cmdPool;
765 Move<VkCommandBuffer> cmdBuffer;
769 Unique<VkDescriptorSetLayout> emptyDescriptorSetLayout (createEmptyDescriptorSetLayout(vk, vkDevice));
770 Unique<VkDescriptorPool> dummyDescriptorPool (createDummyDescriptorPool(vk, vkDevice));
771 Unique<VkDescriptorSet> emptyDescriptorSet (allocateSingleDescriptorSet(vk, vkDevice, *dummyDescriptorPool, *emptyDescriptorSetLayout));
775 // Compute positions - 1px points are used to drive fragment shading.
776 positions = computeVertexPositions(numValues, renderSize.cast<int>());
779 addAttribute(0u, VK_FORMAT_R32G32_SFLOAT, sizeof(tcu::Vec2), (deUint32)positions.size(), &positions[0]);
780 bindAttributes(numValues, inputs);
782 // Create color images
784 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
786 VK_FALSE, // VkBool32 blendEnable;
787 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
788 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
789 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
790 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
791 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destAlphaBlendFactor;
792 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
793 (VK_COLOR_COMPONENT_R_BIT |
794 VK_COLOR_COMPONENT_G_BIT |
795 VK_COLOR_COMPONENT_B_BIT |
796 VK_COLOR_COMPONENT_A_BIT) // VkColorComponentFlags colorWriteMask;
799 for (int outNdx = 0; outNdx < (int)m_outputLayout.locationSymbols.size(); ++outNdx)
801 const bool isFloat = isDataTypeFloatOrVec(m_shaderSpec.outputs[outNdx].varType.getBasicType());
802 const bool isSigned = isDataTypeIntOrIVec (m_shaderSpec.outputs[outNdx].varType.getBasicType());
803 const bool isBool = isDataTypeBoolOrBVec(m_shaderSpec.outputs[outNdx].varType.getBasicType());
804 const VkFormat colorFormat = isFloat ? VK_FORMAT_R32G32B32A32_SFLOAT : (isSigned || isBool ? VK_FORMAT_R32G32B32A32_SINT : VK_FORMAT_R32G32B32A32_UINT);
806 const VkImageCreateInfo colorImageParams =
808 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
809 DE_NULL, // const void* pNext;
810 0u, // VkImageCreateFlags flags;
811 VK_IMAGE_TYPE_2D, // VkImageType imageType;
812 colorFormat, // VkFormat format;
813 { renderSize.x(), renderSize.y(), 1u }, // VkExtent3D extent;
814 1u, // deUint32 mipLevels;
815 1u, // deUint32 arraySize;
816 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
817 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
818 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
819 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
820 1u, // deUint32 queueFamilyCount;
821 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
822 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
825 const VkAttachmentDescription colorAttachmentDescription =
827 0u, // VkAttachmentDescriptorFlags flags;
828 colorFormat, // VkFormat format;
829 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
830 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
831 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
832 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
833 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
834 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
835 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
838 Move<VkImage> colorImage = createImage(vk, vkDevice, &colorImageParams);
839 colorImages.push_back(de::SharedPtr<Unique<VkImage> >(new Unique<VkImage>(colorImage)));
840 attachmentClearValues.push_back(getDefaultClearColor());
842 // Allocate and bind color image memory
844 de::MovePtr<Allocation> colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *((const VkImage*) colorImages.back().get())), MemoryRequirement::Any);
845 VK_CHECK(vk.bindImageMemory(vkDevice, colorImages.back().get()->get(), colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
846 colorImageAllocs.push_back(de::SharedPtr<Allocation>(colorImageAlloc.release()));
848 attachments.push_back(colorAttachmentDescription);
849 colorBlendAttachmentStates.push_back(colorBlendAttachmentState);
851 const VkAttachmentReference colorAttachmentReference =
853 (deUint32) (colorImages.size() - 1), // deUint32 attachment;
854 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
857 colorAttachmentReferences.push_back(colorAttachmentReference);
860 // Create color attachment view
862 const VkImageViewCreateInfo colorImageViewParams =
864 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
865 DE_NULL, // const void* pNext;
866 0u, // VkImageViewCreateFlags flags;
867 colorImages.back().get()->get(), // VkImage image;
868 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
869 colorFormat, // VkFormat format;
871 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
872 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
873 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
874 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
875 }, // VkComponentMapping components;
877 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
878 0u, // deUint32 baseMipLevel;
879 1u, // deUint32 mipLevels;
880 0u, // deUint32 baseArraySlice;
881 1u // deUint32 arraySize;
882 } // VkImageSubresourceRange subresourceRange;
885 Move<VkImageView> colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
886 colorImageViews.push_back(de::SharedPtr<Unique<VkImageView> >(new Unique<VkImageView>(colorImageView)));
888 const VkImageMemoryBarrier colorImagePreRenderBarrier =
890 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
893 (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
894 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), // dstAccessMask
895 VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
896 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
897 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
898 VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex
899 colorImages.back().get()->get(), // image
901 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
904 0u, // baseArrayLayer
906 } // subresourceRange
908 colorImagePreRenderBarriers.push_back(colorImagePreRenderBarrier);
910 const VkImageMemoryBarrier colorImagePostRenderBarrier =
912 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
914 (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
915 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), // srcAccessMask
916 VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask
917 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout
918 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
919 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
920 VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex
921 colorImages.back().get()->get(), // image
923 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
926 0u, // baseArrayLayer
928 } // subresourceRange
930 colorImagePostRenderBarriers.push_back(colorImagePostRenderBarrier);
935 // Create render pass
937 const VkSubpassDescription subpassDescription =
939 0u, // VkSubpassDescriptionFlags flags;
940 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
941 0u, // deUint32 inputCount;
942 DE_NULL, // const VkAttachmentReference* pInputAttachments;
943 (deUint32)colorImages.size(), // deUint32 colorCount;
944 &colorAttachmentReferences[0], // const VkAttachmentReference* colorAttachments;
945 DE_NULL, // const VkAttachmentReference* resolveAttachments;
946 DE_NULL, // VkAttachmentReference depthStencilAttachment;
947 0u, // deUint32 preserveCount;
948 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
951 const VkRenderPassCreateInfo renderPassParams =
953 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
954 DE_NULL, // const void* pNext;
955 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
956 (deUint32)attachments.size(), // deUint32 attachmentCount;
957 &attachments[0], // const VkAttachmentDescription* pAttachments;
958 1u, // deUint32 subpassCount;
959 &subpassDescription, // const VkSubpassDescription* pSubpasses;
960 0u, // deUint32 dependencyCount;
961 DE_NULL // const VkSubpassDependency* pDependencies;
964 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
967 // Create framebuffer
969 std::vector<VkImageView> views(colorImageViews.size());
970 for (size_t i = 0; i < colorImageViews.size(); i++)
972 views[i] = colorImageViews[i].get()->get();
975 const VkFramebufferCreateInfo framebufferParams =
977 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
978 DE_NULL, // const void* pNext;
979 0u, // VkFramebufferCreateFlags flags;
980 *renderPass, // VkRenderPass renderPass;
981 (deUint32)views.size(), // deUint32 attachmentCount;
982 &views[0], // const VkImageView* pAttachments;
983 (deUint32)renderSize.x(), // deUint32 width;
984 (deUint32)renderSize.y(), // deUint32 height;
985 1u // deUint32 layers;
988 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
991 // Create pipeline layout
993 const VkDescriptorSetLayout setLayouts[] =
995 *emptyDescriptorSetLayout,
996 m_extraResourcesLayout
998 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1000 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1001 DE_NULL, // const void* pNext;
1002 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
1003 (m_extraResourcesLayout != 0 ? 2u : 0u), // deUint32 descriptorSetCount;
1004 setLayouts, // const VkDescriptorSetLayout* pSetLayouts;
1005 0u, // deUint32 pushConstantRangeCount;
1006 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1009 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1014 vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
1015 fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
1017 if (useGeometryShader)
1019 geometryShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("geom"), 0);
1025 std::vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
1027 const VkPipelineShaderStageCreateInfo vertexShaderStageParams =
1029 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1030 DE_NULL, // const void* pNext;
1031 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
1032 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
1033 *vertexShaderModule, // VkShaderModule module;
1034 "main", // const char* pName;
1035 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1038 const VkPipelineShaderStageCreateInfo fragmentShaderStageParams =
1040 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1041 DE_NULL, // const void* pNext;
1042 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
1043 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
1044 *fragmentShaderModule, // VkShaderModule module;
1045 "main", // const char* pName;
1046 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1049 shaderStageParams.push_back(vertexShaderStageParams);
1050 shaderStageParams.push_back(fragmentShaderStageParams);
1052 if (useGeometryShader)
1054 const VkPipelineShaderStageCreateInfo geometryShaderStageParams =
1056 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1057 DE_NULL, // const void* pNext;
1058 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
1059 VK_SHADER_STAGE_GEOMETRY_BIT, // VkShaderStageFlagBits stage;
1060 *geometryShaderModule, // VkShaderModule module;
1061 "main", // VkShader shader;
1062 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1065 shaderStageParams.push_back(geometryShaderStageParams);
1068 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1070 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1071 DE_NULL, // const void* pNext;
1072 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
1073 (deUint32)m_vertexBindingDescriptions.size(), // deUint32 bindingCount;
1074 &m_vertexBindingDescriptions[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1075 (deUint32)m_vertexAttributeDescriptions.size(), // deUint32 attributeCount;
1076 &m_vertexAttributeDescriptions[0], // const VkVertexInputAttributeDescription* pvertexAttributeDescriptions;
1079 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
1081 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1082 DE_NULL, // const void* pNext;
1083 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
1084 VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // VkPrimitiveTopology topology;
1085 DE_FALSE // VkBool32 primitiveRestartEnable;
1088 const VkViewport viewport =
1090 0.0f, // float originX;
1091 0.0f, // float originY;
1092 (float)renderSize.x(), // float width;
1093 (float)renderSize.y(), // float height;
1094 0.0f, // float minDepth;
1095 1.0f // float maxDepth;
1098 const VkRect2D scissor =
1103 }, // VkOffset2D offset;
1105 renderSize.x(), // deUint32 width;
1106 renderSize.y(), // deUint32 height;
1107 }, // VkExtent2D extent;
1110 const VkPipelineViewportStateCreateInfo viewportStateParams =
1112 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
1113 DE_NULL, // const void* pNext;
1114 0u, // VkPipelineViewportStateCreateFlags flags;
1115 1u, // deUint32 viewportCount;
1116 &viewport, // const VkViewport* pViewports;
1117 1u, // deUint32 scissorsCount;
1118 &scissor // const VkRect2D* pScissors;
1121 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
1123 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1124 DE_NULL, // const void* pNext;
1125 (VkPipelineRasterizationStateCreateFlags)0u, //VkPipelineRasterizationStateCreateFlags flags;
1126 VK_FALSE, // VkBool32 depthClipEnable;
1127 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
1128 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
1129 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
1130 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
1131 VK_FALSE, // VkBool32 depthBiasEnable;
1132 0.0f, // float depthBias;
1133 0.0f, // float depthBiasClamp;
1134 0.0f, // float slopeScaledDepthBias;
1135 1.0f // float lineWidth;
1138 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1140 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1141 DE_NULL, // const void* pNext;
1142 0u, // VkPipelineMultisampleStateCreateFlags flags;
1143 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
1144 VK_FALSE, // VkBool32 sampleShadingEnable;
1145 0.0f, // float minSampleShading;
1146 DE_NULL, // const VkSampleMask* pSampleMask;
1147 VK_FALSE, // VkBool32 alphaToCoverageEnable;
1148 VK_FALSE // VkBool32 alphaToOneEnable;
1151 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1153 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1154 DE_NULL, // const void* pNext;
1155 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
1156 VK_FALSE, // VkBool32 logicOpEnable;
1157 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1158 (deUint32)colorBlendAttachmentStates.size(), // deUint32 attachmentCount;
1159 &colorBlendAttachmentStates[0], // const VkPipelineColorBlendAttachmentState* pAttachments;
1160 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConst[4];
1163 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1165 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1166 DE_NULL, // const void* pNext;
1167 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
1168 (deUint32)shaderStageParams.size(), // deUint32 stageCount;
1169 &shaderStageParams[0], // const VkPipelineShaderStageCreateInfo* pStages;
1170 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1171 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1172 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1173 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
1174 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
1175 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1176 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1177 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1178 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
1179 *pipelineLayout, // VkPipelineLayout layout;
1180 *renderPass, // VkRenderPass renderPass;
1181 0u, // deUint32 subpass;
1182 0u, // VkPipeline basePipelineHandle;
1183 0u // deInt32 basePipelineIndex;
1186 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1189 // Create command pool
1191 const VkCommandPoolCreateInfo cmdPoolParams =
1193 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
1194 DE_NULL, // const void* pNext;
1195 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
1196 queueFamilyIndex, // deUint32 queueFamilyIndex;
1199 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1202 // Create command buffer
1204 const VkCommandBufferAllocateInfo cmdBufferParams =
1206 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1207 DE_NULL, // const void* pNext;
1208 *cmdPool, // VkCmdPool cmdPool;
1209 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1210 1 // deUint32 bufferCount;
1213 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1215 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1216 DE_NULL, // const void* pNext;
1217 0u, // VkCmdBufferOptimizeFlags flags;
1218 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1221 const VkRenderPassBeginInfo renderPassBeginInfo =
1223 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1224 DE_NULL, // const void* pNext;
1225 *renderPass, // VkRenderPass renderPass;
1226 *framebuffer, // VkFramebuffer framebuffer;
1227 { { 0, 0 }, { renderSize.x(), renderSize.y() } }, // VkRect2D renderArea;
1228 (deUint32)attachmentClearValues.size(), // deUint32 attachmentCount;
1229 &attachmentClearValues[0] // const VkClearValue* pAttachmentClearValues;
1232 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
1234 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1236 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
1237 0, (const VkMemoryBarrier*)DE_NULL,
1238 0, (const VkBufferMemoryBarrier*)DE_NULL,
1239 (deUint32)colorImagePreRenderBarriers.size(), colorImagePreRenderBarriers.empty() ? DE_NULL : &colorImagePreRenderBarriers[0]);
1240 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1242 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
1244 if (m_extraResourcesLayout != 0)
1246 DE_ASSERT(extraResources != 0);
1247 const VkDescriptorSet descriptorSets[] = { *emptyDescriptorSet, extraResources };
1248 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, DE_LENGTH_OF_ARRAY(descriptorSets), descriptorSets, 0u, DE_NULL);
1251 DE_ASSERT(extraResources == 0);
1253 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
1255 std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
1257 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
1258 for (size_t i = 0; i < numberOfVertexAttributes; i++)
1260 buffers[i] = m_vertexBuffers[i].get()->get();
1263 vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
1264 vk.cmdDraw(*cmdBuffer, (deUint32)positions.size(), 1u, 0u, 0u);
1266 vk.cmdEndRenderPass(*cmdBuffer);
1267 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
1268 0, (const VkMemoryBarrier*)DE_NULL,
1269 0, (const VkBufferMemoryBarrier*)DE_NULL,
1270 (deUint32)colorImagePostRenderBarriers.size(), colorImagePostRenderBarriers.empty() ? DE_NULL : &colorImagePostRenderBarriers[0]);
1272 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1277 const VkFenceCreateInfo fenceParams =
1279 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
1280 DE_NULL, // const void* pNext;
1281 0u // VkFenceCreateFlags flags;
1284 fence = createFence(vk, vkDevice, &fenceParams);
1290 const VkSubmitInfo submitInfo =
1292 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
1294 0u, // waitSemaphoreCount
1295 DE_NULL, // pWaitSemaphores
1296 (const VkPipelineStageFlags*)DE_NULL,
1297 1u, // commandBufferCount
1298 &cmdBuffer.get(), // pCommandBuffers
1299 0u, // signalSemaphoreCount
1300 DE_NULL // pSignalSemaphores
1303 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1304 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1305 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), DE_TRUE, ~(0ull) /* infinity*/));
1308 // Read back result and output
1310 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(4 * sizeof(deUint32) * renderSize.x() * renderSize.y());
1311 const VkBufferCreateInfo readImageBufferParams =
1313 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1314 DE_NULL, // const void* pNext;
1315 0u, // VkBufferCreateFlags flags;
1316 imageSizeBytes, // VkDeviceSize size;
1317 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
1318 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1319 1u, // deUint32 queueFamilyCount;
1320 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1323 // constants for image copy
1325 const VkCommandPoolCreateInfo cmdPoolParams =
1327 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
1328 DE_NULL, // const void* pNext;
1329 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
1330 queueFamilyIndex // deUint32 queueFamilyIndex;
1333 Move<VkCommandPool> copyCmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1335 const VkCommandBufferAllocateInfo cmdBufferParams =
1337 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1338 DE_NULL, // const void* pNext;
1339 *copyCmdPool, // VkCmdPool cmdPool;
1340 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1341 1u // deUint32 bufferCount;
1344 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1346 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1347 DE_NULL, // const void* pNext;
1348 0u, // VkCmdBufferOptimizeFlags flags;
1349 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1352 const VkBufferImageCopy copyParams =
1354 0u, // VkDeviceSize bufferOffset;
1355 (deUint32)renderSize.x(), // deUint32 bufferRowLength;
1356 (deUint32)renderSize.y(), // deUint32 bufferImageHeight;
1358 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
1359 0u, // deUint32 mipLevel;
1360 0u, // deUint32 arraySlice;
1361 1u, // deUint32 arraySize;
1362 }, // VkImageSubresource imageSubresource;
1363 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
1364 { renderSize.x(), renderSize.y(), 1u } // VkExtent3D imageExtent;
1367 // Read back pixels.
1368 for (int outNdx = 0; outNdx < (int)m_shaderSpec.outputs.size(); ++outNdx)
1370 const Symbol& output = m_shaderSpec.outputs[outNdx];
1371 const int outSize = output.varType.getScalarSize();
1372 const int outVecSize = glu::getDataTypeNumComponents(output.varType.getBasicType());
1373 const int outNumLocs = glu::getDataTypeNumLocations(output.varType.getBasicType());
1374 deUint32* dstPtrBase = static_cast<deUint32*>(outputs[outNdx]);
1375 const int outLocation = de::lookup(m_outputLayout.locationMap, output.name);
1377 for (int locNdx = 0; locNdx < outNumLocs; ++locNdx)
1379 tcu::TextureLevel tmpBuf;
1380 const tcu::TextureFormat format = getRenderbufferFormatForOutput(output.varType, false);
1381 const tcu::TextureFormat readFormat (tcu::TextureFormat::RGBA, format.type);
1382 const Unique<VkBuffer> readImageBuffer(createBuffer(vk, vkDevice, &readImageBufferParams));
1383 const de::UniquePtr<Allocation> readImageBufferMemory(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
1385 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
1387 // Copy image to buffer
1390 Move<VkCommandBuffer> copyCmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
1392 const VkSubmitInfo submitInfo =
1394 VK_STRUCTURE_TYPE_SUBMIT_INFO,
1397 (const VkSemaphore*)DE_NULL,
1398 (const VkPipelineStageFlags*)DE_NULL,
1400 ©CmdBuffer.get(),
1402 (const VkSemaphore*)DE_NULL,
1405 VK_CHECK(vk.beginCommandBuffer(*copyCmdBuffer, &cmdBufferBeginInfo));
1406 vk.cmdCopyImageToBuffer(*copyCmdBuffer, colorImages[outLocation + locNdx].get()->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params);
1407 VK_CHECK(vk.endCommandBuffer(*copyCmdBuffer));
1409 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1410 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1411 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
1414 const VkMappedMemoryRange range =
1416 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
1417 DE_NULL, // const void* pNext;
1418 readImageBufferMemory->getMemory(), // VkDeviceMemory mem;
1419 0, // VkDeviceSize offset;
1420 imageSizeBytes, // VkDeviceSize size;
1423 VK_CHECK(vk.invalidateMappedMemoryRanges(vkDevice, 1u, &range));
1425 tmpBuf.setStorage(readFormat, renderSize.x(), renderSize.y());
1427 const tcu::TextureFormat resultFormat(tcu::TextureFormat::RGBA, format.type);
1428 const tcu::ConstPixelBufferAccess resultAccess(resultFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr());
1430 tcu::copy(tmpBuf.getAccess(), resultAccess);
1432 if (outSize == 4 && outNumLocs == 1)
1433 deMemcpy(dstPtrBase, tmpBuf.getAccess().getDataPtr(), numValues * outVecSize * sizeof(deUint32));
1436 for (int valNdx = 0; valNdx < numValues; valNdx++)
1438 const deUint32* srcPtr = (const deUint32*)tmpBuf.getAccess().getDataPtr() + valNdx * 4;
1439 deUint32* dstPtr = &dstPtrBase[outSize * valNdx + outVecSize * locNdx];
1440 deMemcpy(dstPtr, srcPtr, outVecSize * sizeof(deUint32));
1448 // VertexShaderExecutor
1450 class VertexShaderExecutor : public FragmentOutExecutor
1453 VertexShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1454 virtual ~VertexShaderExecutor (void);
1456 static void generateSources (const ShaderSpec& shaderSpec, SourceCollections& dst);
1459 VertexShaderExecutor::VertexShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1460 : FragmentOutExecutor(context, glu::SHADERTYPE_VERTEX, shaderSpec, extraResourcesLayout)
1464 VertexShaderExecutor::~VertexShaderExecutor (void)
1468 void VertexShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1470 const FragmentOutputLayout outputLayout (computeFragmentOutputLayout(shaderSpec.outputs));
1472 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShader(shaderSpec, "a_", "vtx_out_"));
1473 /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1474 programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(shaderSpec, false, outputLayout.locationMap, "vtx_out_", "o_"));
1477 // GeometryShaderExecutor
1479 class GeometryShaderExecutor : public FragmentOutExecutor
1482 GeometryShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1483 virtual ~GeometryShaderExecutor (void);
1485 static void generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
1489 GeometryShaderExecutor::GeometryShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1490 : FragmentOutExecutor(context, glu::SHADERTYPE_GEOMETRY, shaderSpec, extraResourcesLayout)
1492 const VkPhysicalDeviceFeatures& features = context.getDeviceFeatures();
1494 if (!features.geometryShader)
1495 TCU_THROW(NotSupportedError, "Geometry shader type not supported by device");
1498 GeometryShaderExecutor::~GeometryShaderExecutor (void)
1502 void GeometryShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1504 const FragmentOutputLayout outputLayout (computeFragmentOutputLayout(shaderSpec.outputs));
1506 programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(shaderSpec.inputs, "a_", "vtx_out_"));
1508 programCollection.glslSources.add("geom") << glu::GeometrySource(generateGeometryShader(shaderSpec, "vtx_out_", "geom_out_"));
1510 /* \todo [2015-09-18 rsipka] set useIntOutputs parameter if needed. */
1511 programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(shaderSpec, false, outputLayout.locationMap, "geom_out_", "o_"));
1515 // FragmentShaderExecutor
1517 class FragmentShaderExecutor : public FragmentOutExecutor
1520 FragmentShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1521 virtual ~FragmentShaderExecutor (void);
1523 static void generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
1527 FragmentShaderExecutor::FragmentShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1528 : FragmentOutExecutor(context, glu::SHADERTYPE_FRAGMENT, shaderSpec, extraResourcesLayout)
1532 FragmentShaderExecutor::~FragmentShaderExecutor (void)
1536 void FragmentShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1538 const FragmentOutputLayout outputLayout (computeFragmentOutputLayout(shaderSpec.outputs));
1540 programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(shaderSpec.inputs, "a_", "vtx_out_"));
1541 /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1542 programCollection.glslSources.add("frag") << glu::FragmentSource(generateFragmentShader(shaderSpec, false, outputLayout.locationMap, "vtx_out_", "o_"));
1545 // Shared utilities for compute and tess executors
1547 static deUint32 getVecStd430ByteAlignment (glu::DataType type)
1549 switch (glu::getDataTypeScalarSize(type))
1561 class BufferIoExecutor : public ShaderExecutor
1564 BufferIoExecutor (Context& context, const ShaderSpec& shaderSpec);
1565 virtual ~BufferIoExecutor (void);
1570 INPUT_BUFFER_BINDING = 0,
1571 OUTPUT_BUFFER_BINDING = 1,
1574 void initBuffers (int numValues);
1575 VkBuffer getInputBuffer (void) const { return *m_inputBuffer; }
1576 VkBuffer getOutputBuffer (void) const { return *m_outputBuffer; }
1577 deUint32 getInputStride (void) const { return getLayoutStride(m_inputLayout); }
1578 deUint32 getOutputStride (void) const { return getLayoutStride(m_outputLayout); }
1580 void uploadInputBuffer (const void* const* inputPtrs, int numValues);
1581 void readOutputBuffer (void* const* outputPtrs, int numValues);
1583 static void declareBufferBlocks (std::ostream& src, const ShaderSpec& spec);
1584 static void generateExecBufferIo(std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName);
1587 Move<VkBuffer> m_inputBuffer;
1588 Move<VkBuffer> m_outputBuffer;
1595 deUint32 matrixStride;
1597 VarLayout (void) : offset(0), stride(0), matrixStride(0) {}
1600 static void computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout);
1601 static deUint32 getLayoutStride (const vector<VarLayout>& layout);
1603 static void copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1604 static void copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1606 de::MovePtr<Allocation> m_inputAlloc;
1607 de::MovePtr<Allocation> m_outputAlloc;
1609 vector<VarLayout> m_inputLayout;
1610 vector<VarLayout> m_outputLayout;
1613 BufferIoExecutor::BufferIoExecutor (Context& context, const ShaderSpec& shaderSpec)
1614 : ShaderExecutor(context, shaderSpec)
1616 computeVarLayout(m_shaderSpec.inputs, &m_inputLayout);
1617 computeVarLayout(m_shaderSpec.outputs, &m_outputLayout);
1620 BufferIoExecutor::~BufferIoExecutor (void)
1624 inline deUint32 BufferIoExecutor::getLayoutStride (const vector<VarLayout>& layout)
1626 return layout.empty() ? 0 : layout[0].stride;
1629 void BufferIoExecutor::computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout)
1631 deUint32 maxAlignment = 0;
1632 deUint32 curOffset = 0;
1634 DE_ASSERT(layout != DE_NULL);
1635 DE_ASSERT(layout->empty());
1636 layout->resize(symbols.size());
1638 for (size_t varNdx = 0; varNdx < symbols.size(); varNdx++)
1640 const Symbol& symbol = symbols[varNdx];
1641 const glu::DataType basicType = symbol.varType.getBasicType();
1642 VarLayout& layoutEntry = (*layout)[varNdx];
1644 if (glu::isDataTypeScalarOrVector(basicType))
1646 const deUint32 alignment = getVecStd430ByteAlignment(basicType);
1647 const deUint32 size = (deUint32)glu::getDataTypeScalarSize(basicType) * (int)sizeof(deUint32);
1649 curOffset = (deUint32)deAlign32((int)curOffset, (int)alignment);
1650 maxAlignment = de::max(maxAlignment, alignment);
1652 layoutEntry.offset = curOffset;
1653 layoutEntry.matrixStride = 0;
1657 else if (glu::isDataTypeMatrix(basicType))
1659 const int numVecs = glu::getDataTypeMatrixNumColumns(basicType);
1660 const glu::DataType vecType = glu::getDataTypeFloatVec(glu::getDataTypeMatrixNumRows(basicType));
1661 const deUint32 vecAlignment = getVecStd430ByteAlignment(vecType);
1663 curOffset = (deUint32)deAlign32((int)curOffset, (int)vecAlignment);
1664 maxAlignment = de::max(maxAlignment, vecAlignment);
1666 layoutEntry.offset = curOffset;
1667 layoutEntry.matrixStride = vecAlignment;
1669 curOffset += vecAlignment*numVecs;
1676 const deUint32 totalSize = (deUint32)deAlign32(curOffset, maxAlignment);
1678 for (vector<VarLayout>::iterator varIter = layout->begin(); varIter != layout->end(); ++varIter)
1679 varIter->stride = totalSize;
1683 void BufferIoExecutor::declareBufferBlocks (std::ostream& src, const ShaderSpec& spec)
1686 if (!spec.inputs.empty())
1688 glu::StructType inputStruct("Inputs");
1689 for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1690 inputStruct.addMember(symIter->name.c_str(), symIter->varType);
1691 src << glu::declare(&inputStruct) << ";\n";
1696 glu::StructType outputStruct("Outputs");
1697 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1698 outputStruct.addMember(symIter->name.c_str(), symIter->varType);
1699 src << glu::declare(&outputStruct) << ";\n";
1704 if (!spec.inputs.empty())
1706 src << "layout(set = 0, binding = " << int(INPUT_BUFFER_BINDING) << ", std430) buffer InBuffer\n"
1708 << " Inputs inputs[];\n"
1712 src << "layout(set = 0, binding = " << int(OUTPUT_BUFFER_BINDING) << ", std430) buffer OutBuffer\n"
1714 << " Outputs outputs[];\n"
1719 void BufferIoExecutor::generateExecBufferIo (std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName)
1721 for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1722 src << "\t" << glu::declare(symIter->varType, symIter->name) << " = inputs[" << invocationNdxName << "]." << symIter->name << ";\n";
1724 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1725 src << "\t" << glu::declare(symIter->varType, symIter->name) << ";\n";
1730 std::istringstream opSrc (spec.source);
1733 while (std::getline(opSrc, line))
1734 src << "\t" << line << "\n";
1738 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1739 src << "\toutputs[" << invocationNdxName << "]." << symIter->name << " = " << symIter->name << ";\n";
1742 void BufferIoExecutor::copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1744 if (varType.isBasicType())
1746 const glu::DataType basicType = varType.getBasicType();
1747 const bool isMatrix = glu::isDataTypeMatrix(basicType);
1748 const int scalarSize = glu::getDataTypeScalarSize(basicType);
1749 const int numVecs = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1750 const int numComps = scalarSize / numVecs;
1752 for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1754 for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1756 const int srcOffset = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1757 const int dstOffset = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1758 const deUint8* srcPtr = (const deUint8*)srcBasePtr + srcOffset;
1759 deUint8* dstPtr = (deUint8*)dstBasePtr + dstOffset;
1761 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1766 throw tcu::InternalError("Unsupported type");
1769 void BufferIoExecutor::copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1771 if (varType.isBasicType())
1773 const glu::DataType basicType = varType.getBasicType();
1774 const bool isMatrix = glu::isDataTypeMatrix(basicType);
1775 const int scalarSize = glu::getDataTypeScalarSize(basicType);
1776 const int numVecs = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1777 const int numComps = scalarSize / numVecs;
1779 for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1781 for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1783 const int srcOffset = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1784 const int dstOffset = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1785 const deUint8* srcPtr = (const deUint8*)srcBasePtr + srcOffset;
1786 deUint8* dstPtr = (deUint8*)dstBasePtr + dstOffset;
1788 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1793 throw tcu::InternalError("Unsupported type");
1796 void BufferIoExecutor::uploadInputBuffer (const void* const* inputPtrs, int numValues)
1798 const VkDevice vkDevice = m_context.getDevice();
1799 const DeviceInterface& vk = m_context.getDeviceInterface();
1801 const deUint32 inputStride = getLayoutStride(m_inputLayout);
1802 const int inputBufferSize = inputStride * numValues;
1804 if (inputBufferSize == 0)
1805 return; // No inputs
1807 DE_ASSERT(m_shaderSpec.inputs.size() == m_inputLayout.size());
1808 for (size_t inputNdx = 0; inputNdx < m_shaderSpec.inputs.size(); ++inputNdx)
1810 const glu::VarType& varType = m_shaderSpec.inputs[inputNdx].varType;
1811 const VarLayout& layout = m_inputLayout[inputNdx];
1813 copyToBuffer(varType, layout, numValues, inputPtrs[inputNdx], m_inputAlloc->getHostPtr());
1816 flushMappedMemoryRange(vk, vkDevice, m_inputAlloc->getMemory(), m_inputAlloc->getOffset(), inputBufferSize);
1819 void BufferIoExecutor::readOutputBuffer (void* const* outputPtrs, int numValues)
1821 const VkDevice vkDevice = m_context.getDevice();
1822 const DeviceInterface& vk = m_context.getDeviceInterface();
1824 const deUint32 outputStride = getLayoutStride(m_outputLayout);
1825 const int outputBufferSize = numValues * outputStride;
1827 DE_ASSERT(outputBufferSize > 0); // At least some outputs are required.
1829 invalidateMappedMemoryRange(vk, vkDevice, m_outputAlloc->getMemory(), m_outputAlloc->getOffset(), outputBufferSize);
1831 DE_ASSERT(m_shaderSpec.outputs.size() == m_outputLayout.size());
1832 for (size_t outputNdx = 0; outputNdx < m_shaderSpec.outputs.size(); ++outputNdx)
1834 const glu::VarType& varType = m_shaderSpec.outputs[outputNdx].varType;
1835 const VarLayout& layout = m_outputLayout[outputNdx];
1837 copyFromBuffer(varType, layout, numValues, m_outputAlloc->getHostPtr(), outputPtrs[outputNdx]);
1841 void BufferIoExecutor::initBuffers (int numValues)
1843 const deUint32 inputStride = getLayoutStride(m_inputLayout);
1844 const deUint32 outputStride = getLayoutStride(m_outputLayout);
1845 // Avoid creating zero-sized buffer/memory
1846 const size_t inputBufferSize = numValues * inputStride ? (numValues * inputStride) : 1;
1847 const size_t outputBufferSize = numValues * outputStride;
1849 // Upload data to buffer
1850 const VkDevice vkDevice = m_context.getDevice();
1851 const DeviceInterface& vk = m_context.getDeviceInterface();
1852 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1853 Allocator& memAlloc = m_context.getDefaultAllocator();
1855 const VkBufferCreateInfo inputBufferParams =
1857 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1858 DE_NULL, // const void* pNext;
1859 0u, // VkBufferCreateFlags flags;
1860 inputBufferSize, // VkDeviceSize size;
1861 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
1862 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1863 1u, // deUint32 queueFamilyCount;
1864 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1867 m_inputBuffer = createBuffer(vk, vkDevice, &inputBufferParams);
1868 m_inputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_inputBuffer), MemoryRequirement::HostVisible);
1870 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_inputBuffer, m_inputAlloc->getMemory(), m_inputAlloc->getOffset()));
1872 const VkBufferCreateInfo outputBufferParams =
1874 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1875 DE_NULL, // const void* pNext;
1876 0u, // VkBufferCreateFlags flags;
1877 outputBufferSize, // VkDeviceSize size;
1878 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
1879 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1880 1u, // deUint32 queueFamilyCount;
1881 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1884 m_outputBuffer = createBuffer(vk, vkDevice, &outputBufferParams);
1885 m_outputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_outputBuffer), MemoryRequirement::HostVisible);
1887 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_outputBuffer, m_outputAlloc->getMemory(), m_outputAlloc->getOffset()));
1890 // ComputeShaderExecutor
1892 class ComputeShaderExecutor : public BufferIoExecutor
1895 ComputeShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1896 virtual ~ComputeShaderExecutor (void);
1898 static void generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
1900 virtual void execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources);
1903 static std::string generateComputeShader (const ShaderSpec& spec);
1906 const VkDescriptorSetLayout m_extraResourcesLayout;
1909 ComputeShaderExecutor::ComputeShaderExecutor(Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1910 : BufferIoExecutor (context, shaderSpec)
1911 , m_extraResourcesLayout (extraResourcesLayout)
1915 ComputeShaderExecutor::~ComputeShaderExecutor (void)
1919 std::string ComputeShaderExecutor::generateComputeShader (const ShaderSpec& spec)
1921 std::ostringstream src;
1922 src << "#version 310 es\n";
1924 if (!spec.globalDeclarations.empty())
1925 src << spec.globalDeclarations << "\n";
1927 src << "layout(local_size_x = 1) in;\n"
1930 declareBufferBlocks(src, spec);
1932 src << "void main (void)\n"
1934 << " uint invocationNdx = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z\n"
1935 << " + gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n";
1937 generateExecBufferIo(src, spec, "invocationNdx");
1944 void ComputeShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1946 programCollection.glslSources.add("compute") << glu::ComputeSource(generateComputeShader(shaderSpec));
1949 void ComputeShaderExecutor::execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources)
1951 const VkDevice vkDevice = m_context.getDevice();
1952 const DeviceInterface& vk = m_context.getDeviceInterface();
1953 const VkQueue queue = m_context.getUniversalQueue();
1954 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1956 DescriptorPoolBuilder descriptorPoolBuilder;
1957 DescriptorSetLayoutBuilder descriptorSetLayoutBuilder;
1959 Move<VkShaderModule> computeShaderModule;
1960 Move<VkPipeline> computePipeline;
1961 Move<VkPipelineLayout> pipelineLayout;
1962 Move<VkCommandPool> cmdPool;
1963 Move<VkDescriptorPool> descriptorPool;
1964 Move<VkDescriptorSetLayout> descriptorSetLayout;
1965 Move<VkDescriptorSet> descriptorSet;
1966 const deUint32 numDescriptorSets = (m_extraResourcesLayout != 0) ? 2u : 1u;
1967 Move<VkFence> fence;
1969 DE_ASSERT((m_extraResourcesLayout != 0) == (extraResources != 0));
1971 initBuffers(numValues);
1973 // Setup input buffer & copy data
1974 uploadInputBuffer(inputs, numValues);
1976 // Create command pool
1978 const VkCommandPoolCreateInfo cmdPoolParams =
1980 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
1981 DE_NULL, // const void* pNext;
1982 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
1983 queueFamilyIndex // deUint32 queueFamilyIndex;
1986 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1989 // Create command buffer
1990 const VkCommandBufferAllocateInfo cmdBufferParams =
1992 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1993 DE_NULL, // const void* pNext;
1994 *cmdPool, // VkCmdPool cmdPool;
1995 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1996 1u // deUint32 bufferCount;
1999 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
2001 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
2002 DE_NULL, // const void* pNext;
2003 0u, // VkCmdBufferOptimizeFlags flags;
2004 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2007 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
2008 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2009 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
2010 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2012 descriptorSetLayout = descriptorSetLayoutBuilder.build(vk, vkDevice);
2013 descriptorPool = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2015 const VkDescriptorSetAllocateInfo allocInfo =
2017 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2021 &*descriptorSetLayout
2024 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2026 // Create pipeline layout
2028 const VkDescriptorSetLayout descriptorSetLayouts[] =
2030 *descriptorSetLayout,
2031 m_extraResourcesLayout
2033 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2035 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
2036 DE_NULL, // const void* pNext;
2037 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
2038 numDescriptorSets, // deUint32 CdescriptorSetCount;
2039 descriptorSetLayouts, // const VkDescriptorSetLayout* pSetLayouts;
2040 0u, // deUint32 pushConstantRangeCount;
2041 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
2044 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2049 computeShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("compute"), 0);
2054 const VkPipelineShaderStageCreateInfo shaderStageParams[1] =
2057 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2058 DE_NULL, // const void* pNext;
2059 (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
2060 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagsBit stage;
2061 *computeShaderModule, // VkShaderModule shader;
2062 "main", // const char* pName;
2063 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2067 const VkComputePipelineCreateInfo computePipelineParams =
2069 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
2070 DE_NULL, // const void* pNext;
2071 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
2072 *shaderStageParams, // VkPipelineShaderStageCreateInfo cs;
2073 *pipelineLayout, // VkPipelineLayout layout;
2074 0u, // VkPipeline basePipelineHandle;
2075 0u, // int32_t basePipelineIndex;
2078 computePipeline = createComputePipeline(vk, vkDevice, DE_NULL, &computePipelineParams);
2083 const VkFenceCreateInfo fenceParams =
2085 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
2086 DE_NULL, // const void* pNext;
2087 0u // VkFenceCreateFlags flags;
2089 fence = createFence(vk, vkDevice, &fenceParams);
2092 const int maxValuesPerInvocation = m_context.getDeviceProperties().limits.maxComputeWorkGroupSize[0];
2094 const deUint32 inputStride = getInputStride();
2095 const deUint32 outputStride = getOutputStride();
2097 while (curOffset < numValues)
2099 Move<VkCommandBuffer> cmdBuffer;
2100 const int numToExec = de::min(maxValuesPerInvocation, numValues-curOffset);
2102 // Update descriptors
2104 DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2106 const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2108 *m_outputBuffer, // VkBuffer buffer;
2109 curOffset * outputStride, // VkDeviceSize offset;
2110 numToExec * outputStride // VkDeviceSize range;
2113 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2117 const VkDescriptorBufferInfo inputDescriptorBufferInfo =
2119 *m_inputBuffer, // VkBuffer buffer;
2120 curOffset * inputStride, // VkDeviceSize offset;
2121 numToExec * inputStride // VkDeviceSize range;
2124 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2127 descriptorSetUpdateBuilder.update(vk, vkDevice);
2130 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
2131 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2132 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
2135 const VkDescriptorSet descriptorSets[] = { *descriptorSet, extraResources };
2136 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, numDescriptorSets, descriptorSets, 0u, DE_NULL);
2139 vk.cmdDispatch(*cmdBuffer, numToExec, 1, 1);
2141 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2143 curOffset += numToExec;
2147 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2149 const VkSubmitInfo submitInfo =
2151 VK_STRUCTURE_TYPE_SUBMIT_INFO,
2154 (const VkSemaphore*)DE_NULL,
2155 (const VkPipelineStageFlags*)DE_NULL,
2159 (const VkSemaphore*)DE_NULL,
2162 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2163 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2168 readOutputBuffer(outputs, numValues);
2171 // Tessellation utils
2173 static std::string generateVertexShaderForTess (void)
2175 std::ostringstream src;
2176 src << "#version 310 es\n"
2177 << "void main (void)\n{\n"
2178 << " gl_Position = vec4(gl_VertexIndex/2, gl_VertexIndex%2, 0.0, 1.0);\n"
2184 class TessellationExecutor : public BufferIoExecutor
2187 TessellationExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
2188 virtual ~TessellationExecutor (void);
2190 void renderTess (deUint32 numValues, deUint32 vertexCount, deUint32 patchControlPoints, VkDescriptorSet extraResources);
2193 const VkDescriptorSetLayout m_extraResourcesLayout;
2196 TessellationExecutor::TessellationExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2197 : BufferIoExecutor (context, shaderSpec)
2198 , m_extraResourcesLayout (extraResourcesLayout)
2200 const VkPhysicalDeviceFeatures& features = context.getDeviceFeatures();
2202 if (!features.tessellationShader)
2203 TCU_THROW(NotSupportedError, "Tessellation shader is not supported by device");
2206 TessellationExecutor::~TessellationExecutor (void)
2210 void TessellationExecutor::renderTess (deUint32 numValues, deUint32 vertexCount, deUint32 patchControlPoints, VkDescriptorSet extraResources)
2212 const size_t inputBufferSize = numValues * getInputStride();
2213 const VkDevice vkDevice = m_context.getDevice();
2214 const DeviceInterface& vk = m_context.getDeviceInterface();
2215 const VkQueue queue = m_context.getUniversalQueue();
2216 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2217 Allocator& memAlloc = m_context.getDefaultAllocator();
2219 const tcu::UVec2 renderSize (DEFAULT_RENDER_WIDTH, DEFAULT_RENDER_HEIGHT);
2221 Move<VkImage> colorImage;
2222 de::MovePtr<Allocation> colorImageAlloc;
2223 VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
2224 Move<VkImageView> colorImageView;
2226 Move<VkRenderPass> renderPass;
2227 Move<VkFramebuffer> framebuffer;
2228 Move<VkPipelineLayout> pipelineLayout;
2229 Move<VkPipeline> graphicsPipeline;
2231 Move<VkShaderModule> vertexShaderModule;
2232 Move<VkShaderModule> tessControlShaderModule;
2233 Move<VkShaderModule> tessEvalShaderModule;
2234 Move<VkShaderModule> fragmentShaderModule;
2236 Move<VkCommandPool> cmdPool;
2237 Move<VkCommandBuffer> cmdBuffer;
2239 Move<VkFence> fence;
2241 Move<VkDescriptorPool> descriptorPool;
2242 Move<VkDescriptorSetLayout> descriptorSetLayout;
2243 Move<VkDescriptorSet> descriptorSet;
2244 const deUint32 numDescriptorSets = (m_extraResourcesLayout != 0) ? 2u : 1u;
2246 DE_ASSERT((m_extraResourcesLayout != 0) == (extraResources != 0));
2248 // Create color image
2250 const VkImageCreateInfo colorImageParams =
2252 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2253 DE_NULL, // const void* pNext;
2254 0u, // VkImageCreateFlags flags;
2255 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2256 colorFormat, // VkFormat format;
2257 { renderSize.x(), renderSize.y(), 1u }, // VkExtent3D extent;
2258 1u, // deUint32 mipLevels;
2259 1u, // deUint32 arraySize;
2260 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2261 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2262 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
2263 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2264 1u, // deUint32 queueFamilyCount;
2265 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2266 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
2269 colorImage = createImage(vk, vkDevice, &colorImageParams);
2271 // Allocate and bind color image memory
2272 colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *colorImage), MemoryRequirement::Any);
2273 VK_CHECK(vk.bindImageMemory(vkDevice, *colorImage, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
2276 // Create color attachment view
2278 const VkImageViewCreateInfo colorImageViewParams =
2280 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2281 DE_NULL, // const void* pNext;
2282 0u, // VkImageViewCreateFlags flags;
2283 *colorImage, // VkImage image;
2284 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2285 colorFormat, // VkFormat format;
2287 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
2288 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
2289 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
2290 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
2291 }, // VkComponentsMapping components;
2293 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2294 0u, // deUint32 baseMipLevel;
2295 1u, // deUint32 mipLevels;
2296 0u, // deUint32 baseArraylayer;
2297 1u // deUint32 layerCount;
2298 } // VkImageSubresourceRange subresourceRange;
2301 colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
2304 // Create render pass
2306 const VkAttachmentDescription colorAttachmentDescription =
2308 0u, // VkAttachmentDescriptorFlags flags;
2309 colorFormat, // VkFormat format;
2310 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2311 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
2312 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2313 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2314 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
2315 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2316 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
2319 const VkAttachmentDescription attachments[1] =
2321 colorAttachmentDescription
2324 const VkAttachmentReference colorAttachmentReference =
2326 0u, // deUint32 attachment;
2327 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
2330 const VkSubpassDescription subpassDescription =
2332 0u, // VkSubpassDescriptionFlags flags;
2333 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
2334 0u, // deUint32 inputCount;
2335 DE_NULL, // const VkAttachmentReference* pInputAttachments;
2336 1u, // deUint32 colorCount;
2337 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
2338 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
2339 DE_NULL, // VkAttachmentReference depthStencilAttachment;
2340 0u, // deUint32 preserveCount;
2341 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
2344 const VkRenderPassCreateInfo renderPassParams =
2346 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
2347 DE_NULL, // const void* pNext;
2348 0u, // VkRenderPassCreateFlags flags;
2349 1u, // deUint32 attachmentCount;
2350 attachments, // const VkAttachmentDescription* pAttachments;
2351 1u, // deUint32 subpassCount;
2352 &subpassDescription, // const VkSubpassDescription* pSubpasses;
2353 0u, // deUint32 dependencyCount;
2354 DE_NULL // const VkSubpassDependency* pDependencies;
2357 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
2360 // Create framebuffer
2362 const VkFramebufferCreateInfo framebufferParams =
2364 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
2365 DE_NULL, // const void* pNext;
2366 0u, // VkFramebufferCreateFlags flags;
2367 *renderPass, // VkRenderPass renderPass;
2368 1u, // deUint32 attachmentCount;
2369 &*colorImageView, // const VkAttachmentBindInfo* pAttachments;
2370 (deUint32)renderSize.x(), // deUint32 width;
2371 (deUint32)renderSize.y(), // deUint32 height;
2372 1u // deUint32 layers;
2375 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
2378 // Create descriptors
2380 DescriptorPoolBuilder descriptorPoolBuilder;
2381 DescriptorSetLayoutBuilder descriptorSetLayoutBuilder;
2383 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2384 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2385 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2386 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2388 descriptorSetLayout = descriptorSetLayoutBuilder.build(vk, vkDevice);
2389 descriptorPool = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2391 const VkDescriptorSetAllocateInfo allocInfo =
2393 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2397 &*descriptorSetLayout
2400 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2401 // Update descriptors
2403 DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2404 const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2406 *m_outputBuffer, // VkBuffer buffer;
2407 0u, // VkDeviceSize offset;
2408 VK_WHOLE_SIZE // VkDeviceSize range;
2411 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2413 VkDescriptorBufferInfo inputDescriptorBufferInfo =
2415 0, // VkBuffer buffer;
2416 0u, // VkDeviceSize offset;
2417 VK_WHOLE_SIZE // VkDeviceSize range;
2420 if (inputBufferSize > 0)
2422 inputDescriptorBufferInfo.buffer = *m_inputBuffer;
2424 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2427 descriptorSetUpdateBuilder.update(vk, vkDevice);
2431 // Create pipeline layout
2433 const VkDescriptorSetLayout descriptorSetLayouts[] =
2435 *descriptorSetLayout,
2436 m_extraResourcesLayout
2438 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2440 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
2441 DE_NULL, // const void* pNext;
2442 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
2443 numDescriptorSets, // deUint32 descriptorSetCount;
2444 descriptorSetLayouts, // const VkDescriptorSetLayout* pSetLayouts;
2445 0u, // deUint32 pushConstantRangeCount;
2446 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
2449 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2452 // Create shader modules
2454 vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
2455 tessControlShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tess_control"), 0);
2456 tessEvalShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tess_eval"), 0);
2457 fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
2462 const VkPipelineShaderStageCreateInfo shaderStageParams[4] =
2465 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2466 DE_NULL, // const void* pNext;
2467 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2468 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBit stage;
2469 *vertexShaderModule, // VkShaderModule shader;
2470 "main", // const char* pName;
2471 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2474 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2475 DE_NULL, // const void* pNext;
2476 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2477 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, // VkShaderStageFlagBit stage;
2478 *tessControlShaderModule, // VkShaderModule shader;
2479 "main", // const char* pName;
2480 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2483 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2484 DE_NULL, // const void* pNext;
2485 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2486 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, // VkShaderStageFlagBit stage;
2487 *tessEvalShaderModule, // VkShaderModule shader;
2488 "main", // const char* pName;
2489 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2492 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2493 DE_NULL, // const void* pNext;
2494 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2495 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBit stage;
2496 *fragmentShaderModule, // VkShaderModule shader;
2497 "main", // const char* pName;
2498 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2502 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
2504 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
2505 DE_NULL, // const void* pNext;
2506 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
2507 0u, // deUint32 bindingCount;
2508 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
2509 0u, // deUint32 attributeCount;
2510 DE_NULL, // const VkVertexInputAttributeDescription* pvertexAttributeDescriptions;
2513 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
2515 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
2516 DE_NULL, // const void* pNext;
2517 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2518 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, // VkPrimitiveTopology topology;
2519 DE_FALSE // VkBool32 primitiveRestartEnable;
2522 struct VkPipelineTessellationStateCreateInfo tessellationStateParams =
2524 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
2525 DE_NULL, // const void* pNext;
2526 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags;
2527 patchControlPoints // uint32_t patchControlPoints;
2530 const VkViewport viewport =
2532 0.0f, // float originX;
2533 0.0f, // float originY;
2534 (float)renderSize.x(), // float width;
2535 (float)renderSize.y(), // float height;
2536 0.0f, // float minDepth;
2537 1.0f // float maxDepth;
2540 const VkRect2D scissor =
2545 }, // VkOffset2D offset;
2547 renderSize.x(), // deUint32 width;
2548 renderSize.y(), // deUint32 height;
2549 }, // VkExtent2D extent;
2552 const VkPipelineViewportStateCreateInfo viewportStateParams =
2554 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
2555 DE_NULL, // const void* pNext;
2556 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewPortStateCreateFlags flags;
2557 1u, // deUint32 viewportCount;
2558 &viewport, // const VkViewport* pViewports;
2559 1u, // deUint32 scissorsCount;
2560 &scissor // const VkRect2D* pScissors;
2563 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
2565 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
2566 DE_NULL, // const void* pNext;
2567 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStageCreateFlags flags;
2568 VK_FALSE, // VkBool32 depthClipEnable;
2569 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
2570 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
2571 VK_CULL_MODE_NONE, // VkCullMode cullMode;
2572 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
2573 VK_FALSE, // VkBool32 depthBiasEnable;
2574 0.0f, // float depthBias;
2575 0.0f, // float depthBiasClamp;
2576 0.0f, // float slopeScaledDepthBias;
2577 1.0f // float lineWidth;
2580 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
2582 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
2583 DE_NULL, // const void* pNext;
2584 0u, // VkPipelineMultisampleStateCreateFlags flags;
2585 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
2586 VK_FALSE, // VkBool32 sampleShadingEnable;
2587 0.0f, // float minSampleShading;
2588 DE_NULL, // const VkSampleMask* pSampleMask;
2589 VK_FALSE, // VkBool32 alphaToCoverageEnable;
2590 VK_FALSE // VkBool32 alphaToOneEnable;
2593 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
2595 VK_FALSE, // VkBool32 blendEnable;
2596 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcBlendColor;
2597 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destBlendColor;
2598 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
2599 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcBlendAlpha;
2600 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destBlendAlpha;
2601 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
2602 (VK_COLOR_COMPONENT_R_BIT |
2603 VK_COLOR_COMPONENT_G_BIT |
2604 VK_COLOR_COMPONENT_B_BIT |
2605 VK_COLOR_COMPONENT_A_BIT) // VkColorComponentFlags colorWriteMask;
2608 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
2610 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
2611 DE_NULL, // const void* pNext;
2612 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags
2613 VK_FALSE, // VkBool32 logicOpEnable;
2614 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
2615 1u, // deUint32 attachmentCount;
2616 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
2617 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConst[4];
2620 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
2622 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
2623 DE_NULL, // const void* pNext;
2624 0u, // VkPipelineCreateFlags flags;
2625 4u, // deUint32 stageCount;
2626 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages;
2627 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
2628 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
2629 &tessellationStateParams, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
2630 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
2631 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
2632 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
2633 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
2634 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
2635 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
2636 *pipelineLayout, // VkPipelineLayout layout;
2637 *renderPass, // VkRenderPass renderPass;
2638 0u, // deUint32 subpass;
2639 0u, // VkPipeline basePipelineHandle;
2640 0u // deInt32 basePipelineIndex;
2643 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
2646 // Create command pool
2648 const VkCommandPoolCreateInfo cmdPoolParams =
2650 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
2651 DE_NULL, // const void* pNext;
2652 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
2653 queueFamilyIndex, // deUint32 queueFamilyIndex;
2656 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
2659 // Create command buffer
2661 const VkCommandBufferAllocateInfo cmdBufferParams =
2663 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
2664 DE_NULL, // const void* pNext;
2665 *cmdPool, // VkCmdPool cmdPool;
2666 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
2667 1u // uint32_t bufferCount;
2670 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
2672 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
2673 DE_NULL, // const void* pNext;
2674 0u, // VkCmdBufferOptimizeFlags flags;
2675 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2678 const VkClearValue clearValues[1] =
2680 getDefaultClearColor()
2683 const VkRenderPassBeginInfo renderPassBeginInfo =
2685 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
2686 DE_NULL, // const void* pNext;
2687 *renderPass, // VkRenderPass renderPass;
2688 *framebuffer, // VkFramebuffer framebuffer;
2689 { { 0, 0 }, { renderSize.x(), renderSize.y() } }, // VkRect2D renderArea;
2690 1, // deUint32 attachmentCount;
2691 clearValues // const VkClearValue* pClearValues;
2694 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
2696 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2698 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2700 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
2703 const VkDescriptorSet descriptorSets[] = { *descriptorSet, extraResources };
2704 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, numDescriptorSets, descriptorSets, 0u, DE_NULL);
2707 vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
2709 vk.cmdEndRenderPass(*cmdBuffer);
2710 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2715 const VkFenceCreateInfo fenceParams =
2717 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
2718 DE_NULL, // const void* pNext;
2719 0u // VkFenceCreateFlags flags;
2721 fence = createFence(vk, vkDevice, &fenceParams);
2726 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2727 const VkSubmitInfo submitInfo =
2729 VK_STRUCTURE_TYPE_SUBMIT_INFO,
2732 (const VkSemaphore*)0,
2733 (const VkPipelineStageFlags*)DE_NULL,
2737 (const VkSemaphore*)0,
2739 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2740 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2744 // TessControlExecutor
2746 class TessControlExecutor : public TessellationExecutor
2749 TessControlExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
2750 virtual ~TessControlExecutor (void);
2752 static void generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
2754 virtual void execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources);
2757 static std::string generateTessControlShader (const ShaderSpec& shaderSpec);
2760 TessControlExecutor::TessControlExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2761 : TessellationExecutor(context, shaderSpec, extraResourcesLayout)
2765 TessControlExecutor::~TessControlExecutor (void)
2769 std::string TessControlExecutor::generateTessControlShader (const ShaderSpec& shaderSpec)
2771 std::ostringstream src;
2772 src << "#version 310 es\n"
2773 "#extension GL_EXT_tessellation_shader : require\n\n";
2775 if (!shaderSpec.globalDeclarations.empty())
2776 src << shaderSpec.globalDeclarations << "\n";
2778 src << "\nlayout(vertices = 1) out;\n\n";
2780 declareBufferBlocks(src, shaderSpec);
2782 src << "void main (void)\n{\n";
2784 for (int ndx = 0; ndx < 2; ndx++)
2785 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2787 for (int ndx = 0; ndx < 4; ndx++)
2788 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2791 << "\thighp uint invocationId = uint(gl_PrimitiveID);\n";
2793 generateExecBufferIo(src, shaderSpec, "invocationId");
2800 static std::string generateEmptyTessEvalShader ()
2802 std::ostringstream src;
2804 src << "#version 310 es\n"
2805 "#extension GL_EXT_tessellation_shader : require\n\n";
2807 src << "layout(triangles, ccw) in;\n";
2809 src << "\nvoid main (void)\n{\n"
2810 << "\tgl_Position = vec4(gl_TessCoord.xy, 0.0, 1.0);\n"
2816 void TessControlExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
2818 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess());
2819 programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generateTessControlShader(shaderSpec));
2820 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateEmptyTessEvalShader());
2821 programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource());
2824 void TessControlExecutor::execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources)
2826 const deUint32 patchSize = 3;
2828 initBuffers(numValues);
2830 // Setup input buffer & copy data
2831 uploadInputBuffer(inputs, numValues);
2833 renderTess(numValues, patchSize * numValues, patchSize, extraResources);
2836 readOutputBuffer(outputs, numValues);
2839 // TessEvaluationExecutor
2841 class TessEvaluationExecutor : public TessellationExecutor
2844 TessEvaluationExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
2845 virtual ~TessEvaluationExecutor (void);
2847 static void generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
2849 virtual void execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources);
2852 static std::string generateTessEvalShader (const ShaderSpec& shaderSpec);
2855 TessEvaluationExecutor::TessEvaluationExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2856 : TessellationExecutor (context, shaderSpec, extraResourcesLayout)
2860 TessEvaluationExecutor::~TessEvaluationExecutor (void)
2864 static std::string generatePassthroughTessControlShader (void)
2866 std::ostringstream src;
2868 src << "#version 310 es\n"
2869 "#extension GL_EXT_tessellation_shader : require\n\n";
2871 src << "layout(vertices = 1) out;\n\n";
2873 src << "void main (void)\n{\n";
2875 for (int ndx = 0; ndx < 2; ndx++)
2876 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2878 for (int ndx = 0; ndx < 4; ndx++)
2879 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2886 std::string TessEvaluationExecutor::generateTessEvalShader (const ShaderSpec& shaderSpec)
2888 std::ostringstream src;
2890 src << "#version 310 es\n"
2891 "#extension GL_EXT_tessellation_shader : require\n\n";
2893 if (!shaderSpec.globalDeclarations.empty())
2894 src << shaderSpec.globalDeclarations << "\n";
2898 src << "layout(isolines, equal_spacing) in;\n\n";
2900 declareBufferBlocks(src, shaderSpec);
2902 src << "void main (void)\n{\n"
2903 << "\tgl_Position = vec4(gl_TessCoord.x, 0.0, 0.0, 1.0);\n"
2904 << "\thighp uint invocationId = uint(gl_PrimitiveID)*2u + (gl_TessCoord.x > 0.5 ? 1u : 0u);\n";
2906 generateExecBufferIo(src, shaderSpec, "invocationId");
2913 void TessEvaluationExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
2915 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess());
2916 programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generatePassthroughTessControlShader());
2917 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateTessEvalShader(shaderSpec));
2918 programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource());
2921 void TessEvaluationExecutor::execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources)
2923 const int patchSize = 2;
2924 const int alignedValues = deAlign32(numValues, patchSize);
2926 // Initialize buffers with aligned value count to make room for padding
2927 initBuffers(alignedValues);
2929 // Setup input buffer & copy data
2930 uploadInputBuffer(inputs, numValues);
2932 renderTess((deUint32)alignedValues, (deUint32)alignedValues, (deUint32)patchSize, extraResources);
2935 readOutputBuffer(outputs, numValues);
2942 ShaderExecutor::~ShaderExecutor (void)
2948 void generateSources (glu::ShaderType shaderType, const ShaderSpec& shaderSpec, vk::SourceCollections& dst)
2952 case glu::SHADERTYPE_VERTEX: VertexShaderExecutor::generateSources (shaderSpec, dst); break;
2953 case glu::SHADERTYPE_TESSELLATION_CONTROL: TessControlExecutor::generateSources (shaderSpec, dst); break;
2954 case glu::SHADERTYPE_TESSELLATION_EVALUATION: TessEvaluationExecutor::generateSources (shaderSpec, dst); break;
2955 case glu::SHADERTYPE_GEOMETRY: GeometryShaderExecutor::generateSources (shaderSpec, dst); break;
2956 case glu::SHADERTYPE_FRAGMENT: FragmentShaderExecutor::generateSources (shaderSpec, dst); break;
2957 case glu::SHADERTYPE_COMPUTE: ComputeShaderExecutor::generateSources (shaderSpec, dst); break;
2959 TCU_THROW(InternalError, "Unsupported shader type");
2963 ShaderExecutor* createExecutor (Context& context, glu::ShaderType shaderType, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2967 case glu::SHADERTYPE_VERTEX: return new VertexShaderExecutor (context, shaderSpec, extraResourcesLayout);
2968 case glu::SHADERTYPE_TESSELLATION_CONTROL: return new TessControlExecutor (context, shaderSpec, extraResourcesLayout);
2969 case glu::SHADERTYPE_TESSELLATION_EVALUATION: return new TessEvaluationExecutor (context, shaderSpec, extraResourcesLayout);
2970 case glu::SHADERTYPE_GEOMETRY: return new GeometryShaderExecutor (context, shaderSpec, extraResourcesLayout);
2971 case glu::SHADERTYPE_FRAGMENT: return new FragmentShaderExecutor (context, shaderSpec, extraResourcesLayout);
2972 case glu::SHADERTYPE_COMPUTE: return new ComputeShaderExecutor (context, shaderSpec, extraResourcesLayout);
2974 TCU_THROW(InternalError, "Unsupported shader type");