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
1190 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1192 // Create command buffer
1194 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1196 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1197 DE_NULL, // const void* pNext;
1198 0u, // VkCmdBufferOptimizeFlags flags;
1199 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1202 const VkRenderPassBeginInfo renderPassBeginInfo =
1204 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1205 DE_NULL, // const void* pNext;
1206 *renderPass, // VkRenderPass renderPass;
1207 *framebuffer, // VkFramebuffer framebuffer;
1208 { { 0, 0 }, { renderSize.x(), renderSize.y() } }, // VkRect2D renderArea;
1209 (deUint32)attachmentClearValues.size(), // deUint32 attachmentCount;
1210 &attachmentClearValues[0] // const VkClearValue* pAttachmentClearValues;
1213 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1215 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1217 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
1218 0, (const VkMemoryBarrier*)DE_NULL,
1219 0, (const VkBufferMemoryBarrier*)DE_NULL,
1220 (deUint32)colorImagePreRenderBarriers.size(), colorImagePreRenderBarriers.empty() ? DE_NULL : &colorImagePreRenderBarriers[0]);
1221 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1223 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
1225 if (m_extraResourcesLayout != 0)
1227 DE_ASSERT(extraResources != 0);
1228 const VkDescriptorSet descriptorSets[] = { *emptyDescriptorSet, extraResources };
1229 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, DE_LENGTH_OF_ARRAY(descriptorSets), descriptorSets, 0u, DE_NULL);
1232 DE_ASSERT(extraResources == 0);
1234 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
1236 std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
1238 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
1239 for (size_t i = 0; i < numberOfVertexAttributes; i++)
1241 buffers[i] = m_vertexBuffers[i].get()->get();
1244 vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
1245 vk.cmdDraw(*cmdBuffer, (deUint32)positions.size(), 1u, 0u, 0u);
1247 vk.cmdEndRenderPass(*cmdBuffer);
1248 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
1249 0, (const VkMemoryBarrier*)DE_NULL,
1250 0, (const VkBufferMemoryBarrier*)DE_NULL,
1251 (deUint32)colorImagePostRenderBarriers.size(), colorImagePostRenderBarriers.empty() ? DE_NULL : &colorImagePostRenderBarriers[0]);
1253 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1257 fence = createFence(vk, vkDevice);
1262 const VkSubmitInfo submitInfo =
1264 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
1266 0u, // waitSemaphoreCount
1267 DE_NULL, // pWaitSemaphores
1268 (const VkPipelineStageFlags*)DE_NULL,
1269 1u, // commandBufferCount
1270 &cmdBuffer.get(), // pCommandBuffers
1271 0u, // signalSemaphoreCount
1272 DE_NULL // pSignalSemaphores
1275 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1276 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1277 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), DE_TRUE, ~(0ull) /* infinity*/));
1280 // Read back result and output
1282 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(4 * sizeof(deUint32) * renderSize.x() * renderSize.y());
1283 const VkBufferCreateInfo readImageBufferParams =
1285 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1286 DE_NULL, // const void* pNext;
1287 0u, // VkBufferCreateFlags flags;
1288 imageSizeBytes, // VkDeviceSize size;
1289 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
1290 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1291 1u, // deUint32 queueFamilyCount;
1292 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1295 // constants for image copy
1296 Move<VkCommandPool> copyCmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1298 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1300 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1301 DE_NULL, // const void* pNext;
1302 0u, // VkCmdBufferOptimizeFlags flags;
1303 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1306 const VkBufferImageCopy copyParams =
1308 0u, // VkDeviceSize bufferOffset;
1309 (deUint32)renderSize.x(), // deUint32 bufferRowLength;
1310 (deUint32)renderSize.y(), // deUint32 bufferImageHeight;
1312 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
1313 0u, // deUint32 mipLevel;
1314 0u, // deUint32 arraySlice;
1315 1u, // deUint32 arraySize;
1316 }, // VkImageSubresource imageSubresource;
1317 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
1318 { renderSize.x(), renderSize.y(), 1u } // VkExtent3D imageExtent;
1321 // Read back pixels.
1322 for (int outNdx = 0; outNdx < (int)m_shaderSpec.outputs.size(); ++outNdx)
1324 const Symbol& output = m_shaderSpec.outputs[outNdx];
1325 const int outSize = output.varType.getScalarSize();
1326 const int outVecSize = glu::getDataTypeNumComponents(output.varType.getBasicType());
1327 const int outNumLocs = glu::getDataTypeNumLocations(output.varType.getBasicType());
1328 deUint32* dstPtrBase = static_cast<deUint32*>(outputs[outNdx]);
1329 const int outLocation = de::lookup(m_outputLayout.locationMap, output.name);
1331 for (int locNdx = 0; locNdx < outNumLocs; ++locNdx)
1333 tcu::TextureLevel tmpBuf;
1334 const tcu::TextureFormat format = getRenderbufferFormatForOutput(output.varType, false);
1335 const tcu::TextureFormat readFormat (tcu::TextureFormat::RGBA, format.type);
1336 const Unique<VkBuffer> readImageBuffer(createBuffer(vk, vkDevice, &readImageBufferParams));
1337 const de::UniquePtr<Allocation> readImageBufferMemory(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
1339 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
1341 // Copy image to buffer
1344 Move<VkCommandBuffer> copyCmdBuffer = allocateCommandBuffer(vk, vkDevice, *copyCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1346 const VkSubmitInfo submitInfo =
1348 VK_STRUCTURE_TYPE_SUBMIT_INFO,
1351 (const VkSemaphore*)DE_NULL,
1352 (const VkPipelineStageFlags*)DE_NULL,
1354 ©CmdBuffer.get(),
1356 (const VkSemaphore*)DE_NULL,
1359 VK_CHECK(vk.beginCommandBuffer(*copyCmdBuffer, &cmdBufferBeginInfo));
1360 vk.cmdCopyImageToBuffer(*copyCmdBuffer, colorImages[outLocation + locNdx].get()->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params);
1361 VK_CHECK(vk.endCommandBuffer(*copyCmdBuffer));
1363 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1364 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1365 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
1368 const VkMappedMemoryRange range =
1370 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
1371 DE_NULL, // const void* pNext;
1372 readImageBufferMemory->getMemory(), // VkDeviceMemory mem;
1373 0, // VkDeviceSize offset;
1374 imageSizeBytes, // VkDeviceSize size;
1377 VK_CHECK(vk.invalidateMappedMemoryRanges(vkDevice, 1u, &range));
1379 tmpBuf.setStorage(readFormat, renderSize.x(), renderSize.y());
1381 const tcu::TextureFormat resultFormat(tcu::TextureFormat::RGBA, format.type);
1382 const tcu::ConstPixelBufferAccess resultAccess(resultFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr());
1384 tcu::copy(tmpBuf.getAccess(), resultAccess);
1386 if (outSize == 4 && outNumLocs == 1)
1387 deMemcpy(dstPtrBase, tmpBuf.getAccess().getDataPtr(), numValues * outVecSize * sizeof(deUint32));
1390 for (int valNdx = 0; valNdx < numValues; valNdx++)
1392 const deUint32* srcPtr = (const deUint32*)tmpBuf.getAccess().getDataPtr() + valNdx * 4;
1393 deUint32* dstPtr = &dstPtrBase[outSize * valNdx + outVecSize * locNdx];
1394 deMemcpy(dstPtr, srcPtr, outVecSize * sizeof(deUint32));
1402 // VertexShaderExecutor
1404 class VertexShaderExecutor : public FragmentOutExecutor
1407 VertexShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1408 virtual ~VertexShaderExecutor (void);
1410 static void generateSources (const ShaderSpec& shaderSpec, SourceCollections& dst);
1413 VertexShaderExecutor::VertexShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1414 : FragmentOutExecutor(context, glu::SHADERTYPE_VERTEX, shaderSpec, extraResourcesLayout)
1418 VertexShaderExecutor::~VertexShaderExecutor (void)
1422 void VertexShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1424 const FragmentOutputLayout outputLayout (computeFragmentOutputLayout(shaderSpec.outputs));
1426 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShader(shaderSpec, "a_", "vtx_out_")) << shaderSpec.buildOptions;
1427 /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1428 programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(shaderSpec, false, outputLayout.locationMap, "vtx_out_", "o_")) << shaderSpec.buildOptions;
1431 // GeometryShaderExecutor
1433 class GeometryShaderExecutor : public FragmentOutExecutor
1436 GeometryShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1437 virtual ~GeometryShaderExecutor (void);
1439 static void generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
1443 GeometryShaderExecutor::GeometryShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1444 : FragmentOutExecutor(context, glu::SHADERTYPE_GEOMETRY, shaderSpec, extraResourcesLayout)
1446 const VkPhysicalDeviceFeatures& features = context.getDeviceFeatures();
1448 if (!features.geometryShader)
1449 TCU_THROW(NotSupportedError, "Geometry shader type not supported by device");
1452 GeometryShaderExecutor::~GeometryShaderExecutor (void)
1456 void GeometryShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1458 const FragmentOutputLayout outputLayout (computeFragmentOutputLayout(shaderSpec.outputs));
1460 programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(shaderSpec.inputs, "a_", "vtx_out_")) << shaderSpec.buildOptions;
1462 programCollection.glslSources.add("geom") << glu::GeometrySource(generateGeometryShader(shaderSpec, "vtx_out_", "geom_out_")) << shaderSpec.buildOptions;
1464 /* \todo [2015-09-18 rsipka] set useIntOutputs parameter if needed. */
1465 programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(shaderSpec, false, outputLayout.locationMap, "geom_out_", "o_")) << shaderSpec.buildOptions;
1469 // FragmentShaderExecutor
1471 class FragmentShaderExecutor : public FragmentOutExecutor
1474 FragmentShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1475 virtual ~FragmentShaderExecutor (void);
1477 static void generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
1481 FragmentShaderExecutor::FragmentShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1482 : FragmentOutExecutor(context, glu::SHADERTYPE_FRAGMENT, shaderSpec, extraResourcesLayout)
1486 FragmentShaderExecutor::~FragmentShaderExecutor (void)
1490 void FragmentShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1492 const FragmentOutputLayout outputLayout (computeFragmentOutputLayout(shaderSpec.outputs));
1494 programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(shaderSpec.inputs, "a_", "vtx_out_")) << shaderSpec.buildOptions;
1495 /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1496 programCollection.glslSources.add("frag") << glu::FragmentSource(generateFragmentShader(shaderSpec, false, outputLayout.locationMap, "vtx_out_", "o_")) << shaderSpec.buildOptions;
1499 // Shared utilities for compute and tess executors
1501 static deUint32 getVecStd430ByteAlignment (glu::DataType type)
1503 switch (glu::getDataTypeScalarSize(type))
1515 class BufferIoExecutor : public ShaderExecutor
1518 BufferIoExecutor (Context& context, const ShaderSpec& shaderSpec);
1519 virtual ~BufferIoExecutor (void);
1524 INPUT_BUFFER_BINDING = 0,
1525 OUTPUT_BUFFER_BINDING = 1,
1528 void initBuffers (int numValues);
1529 VkBuffer getInputBuffer (void) const { return *m_inputBuffer; }
1530 VkBuffer getOutputBuffer (void) const { return *m_outputBuffer; }
1531 deUint32 getInputStride (void) const { return getLayoutStride(m_inputLayout); }
1532 deUint32 getOutputStride (void) const { return getLayoutStride(m_outputLayout); }
1534 void uploadInputBuffer (const void* const* inputPtrs, int numValues);
1535 void readOutputBuffer (void* const* outputPtrs, int numValues);
1537 static void declareBufferBlocks (std::ostream& src, const ShaderSpec& spec);
1538 static void generateExecBufferIo(std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName);
1541 Move<VkBuffer> m_inputBuffer;
1542 Move<VkBuffer> m_outputBuffer;
1549 deUint32 matrixStride;
1551 VarLayout (void) : offset(0), stride(0), matrixStride(0) {}
1554 static void computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout);
1555 static deUint32 getLayoutStride (const vector<VarLayout>& layout);
1557 static void copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1558 static void copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1560 de::MovePtr<Allocation> m_inputAlloc;
1561 de::MovePtr<Allocation> m_outputAlloc;
1563 vector<VarLayout> m_inputLayout;
1564 vector<VarLayout> m_outputLayout;
1567 BufferIoExecutor::BufferIoExecutor (Context& context, const ShaderSpec& shaderSpec)
1568 : ShaderExecutor(context, shaderSpec)
1570 computeVarLayout(m_shaderSpec.inputs, &m_inputLayout);
1571 computeVarLayout(m_shaderSpec.outputs, &m_outputLayout);
1574 BufferIoExecutor::~BufferIoExecutor (void)
1578 inline deUint32 BufferIoExecutor::getLayoutStride (const vector<VarLayout>& layout)
1580 return layout.empty() ? 0 : layout[0].stride;
1583 void BufferIoExecutor::computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout)
1585 deUint32 maxAlignment = 0;
1586 deUint32 curOffset = 0;
1588 DE_ASSERT(layout != DE_NULL);
1589 DE_ASSERT(layout->empty());
1590 layout->resize(symbols.size());
1592 for (size_t varNdx = 0; varNdx < symbols.size(); varNdx++)
1594 const Symbol& symbol = symbols[varNdx];
1595 const glu::DataType basicType = symbol.varType.getBasicType();
1596 VarLayout& layoutEntry = (*layout)[varNdx];
1598 if (glu::isDataTypeScalarOrVector(basicType))
1600 const deUint32 alignment = getVecStd430ByteAlignment(basicType);
1601 const deUint32 size = (deUint32)glu::getDataTypeScalarSize(basicType) * (int)sizeof(deUint32);
1603 curOffset = (deUint32)deAlign32((int)curOffset, (int)alignment);
1604 maxAlignment = de::max(maxAlignment, alignment);
1606 layoutEntry.offset = curOffset;
1607 layoutEntry.matrixStride = 0;
1611 else if (glu::isDataTypeMatrix(basicType))
1613 const int numVecs = glu::getDataTypeMatrixNumColumns(basicType);
1614 const glu::DataType vecType = glu::getDataTypeFloatVec(glu::getDataTypeMatrixNumRows(basicType));
1615 const deUint32 vecAlignment = getVecStd430ByteAlignment(vecType);
1617 curOffset = (deUint32)deAlign32((int)curOffset, (int)vecAlignment);
1618 maxAlignment = de::max(maxAlignment, vecAlignment);
1620 layoutEntry.offset = curOffset;
1621 layoutEntry.matrixStride = vecAlignment;
1623 curOffset += vecAlignment*numVecs;
1630 const deUint32 totalSize = (deUint32)deAlign32(curOffset, maxAlignment);
1632 for (vector<VarLayout>::iterator varIter = layout->begin(); varIter != layout->end(); ++varIter)
1633 varIter->stride = totalSize;
1637 void BufferIoExecutor::declareBufferBlocks (std::ostream& src, const ShaderSpec& spec)
1640 if (!spec.inputs.empty())
1642 glu::StructType inputStruct("Inputs");
1643 for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1644 inputStruct.addMember(symIter->name.c_str(), symIter->varType);
1645 src << glu::declare(&inputStruct) << ";\n";
1650 glu::StructType outputStruct("Outputs");
1651 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1652 outputStruct.addMember(symIter->name.c_str(), symIter->varType);
1653 src << glu::declare(&outputStruct) << ";\n";
1658 if (!spec.inputs.empty())
1660 src << "layout(set = 0, binding = " << int(INPUT_BUFFER_BINDING) << ", std430) buffer InBuffer\n"
1662 << " Inputs inputs[];\n"
1666 src << "layout(set = 0, binding = " << int(OUTPUT_BUFFER_BINDING) << ", std430) buffer OutBuffer\n"
1668 << " Outputs outputs[];\n"
1673 void BufferIoExecutor::generateExecBufferIo (std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName)
1675 for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1676 src << "\t" << glu::declare(symIter->varType, symIter->name) << " = inputs[" << invocationNdxName << "]." << symIter->name << ";\n";
1678 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1679 src << "\t" << glu::declare(symIter->varType, symIter->name) << ";\n";
1684 std::istringstream opSrc (spec.source);
1687 while (std::getline(opSrc, line))
1688 src << "\t" << line << "\n";
1692 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1693 src << "\toutputs[" << invocationNdxName << "]." << symIter->name << " = " << symIter->name << ";\n";
1696 void BufferIoExecutor::copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1698 if (varType.isBasicType())
1700 const glu::DataType basicType = varType.getBasicType();
1701 const bool isMatrix = glu::isDataTypeMatrix(basicType);
1702 const int scalarSize = glu::getDataTypeScalarSize(basicType);
1703 const int numVecs = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1704 const int numComps = scalarSize / numVecs;
1706 for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1708 for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1710 const int srcOffset = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1711 const int dstOffset = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1712 const deUint8* srcPtr = (const deUint8*)srcBasePtr + srcOffset;
1713 deUint8* dstPtr = (deUint8*)dstBasePtr + dstOffset;
1715 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1720 throw tcu::InternalError("Unsupported type");
1723 void BufferIoExecutor::copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1725 if (varType.isBasicType())
1727 const glu::DataType basicType = varType.getBasicType();
1728 const bool isMatrix = glu::isDataTypeMatrix(basicType);
1729 const int scalarSize = glu::getDataTypeScalarSize(basicType);
1730 const int numVecs = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1731 const int numComps = scalarSize / numVecs;
1733 for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1735 for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1737 const int srcOffset = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1738 const int dstOffset = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1739 const deUint8* srcPtr = (const deUint8*)srcBasePtr + srcOffset;
1740 deUint8* dstPtr = (deUint8*)dstBasePtr + dstOffset;
1742 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1747 throw tcu::InternalError("Unsupported type");
1750 void BufferIoExecutor::uploadInputBuffer (const void* const* inputPtrs, int numValues)
1752 const VkDevice vkDevice = m_context.getDevice();
1753 const DeviceInterface& vk = m_context.getDeviceInterface();
1755 const deUint32 inputStride = getLayoutStride(m_inputLayout);
1756 const int inputBufferSize = inputStride * numValues;
1758 if (inputBufferSize == 0)
1759 return; // No inputs
1761 DE_ASSERT(m_shaderSpec.inputs.size() == m_inputLayout.size());
1762 for (size_t inputNdx = 0; inputNdx < m_shaderSpec.inputs.size(); ++inputNdx)
1764 const glu::VarType& varType = m_shaderSpec.inputs[inputNdx].varType;
1765 const VarLayout& layout = m_inputLayout[inputNdx];
1767 copyToBuffer(varType, layout, numValues, inputPtrs[inputNdx], m_inputAlloc->getHostPtr());
1770 flushMappedMemoryRange(vk, vkDevice, m_inputAlloc->getMemory(), m_inputAlloc->getOffset(), inputBufferSize);
1773 void BufferIoExecutor::readOutputBuffer (void* const* outputPtrs, int numValues)
1775 const VkDevice vkDevice = m_context.getDevice();
1776 const DeviceInterface& vk = m_context.getDeviceInterface();
1778 const deUint32 outputStride = getLayoutStride(m_outputLayout);
1779 const int outputBufferSize = numValues * outputStride;
1781 DE_ASSERT(outputBufferSize > 0); // At least some outputs are required.
1783 invalidateMappedMemoryRange(vk, vkDevice, m_outputAlloc->getMemory(), m_outputAlloc->getOffset(), outputBufferSize);
1785 DE_ASSERT(m_shaderSpec.outputs.size() == m_outputLayout.size());
1786 for (size_t outputNdx = 0; outputNdx < m_shaderSpec.outputs.size(); ++outputNdx)
1788 const glu::VarType& varType = m_shaderSpec.outputs[outputNdx].varType;
1789 const VarLayout& layout = m_outputLayout[outputNdx];
1791 copyFromBuffer(varType, layout, numValues, m_outputAlloc->getHostPtr(), outputPtrs[outputNdx]);
1795 void BufferIoExecutor::initBuffers (int numValues)
1797 const deUint32 inputStride = getLayoutStride(m_inputLayout);
1798 const deUint32 outputStride = getLayoutStride(m_outputLayout);
1799 // Avoid creating zero-sized buffer/memory
1800 const size_t inputBufferSize = numValues * inputStride ? (numValues * inputStride) : 1;
1801 const size_t outputBufferSize = numValues * outputStride;
1803 // Upload data to buffer
1804 const VkDevice vkDevice = m_context.getDevice();
1805 const DeviceInterface& vk = m_context.getDeviceInterface();
1806 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1807 Allocator& memAlloc = m_context.getDefaultAllocator();
1809 const VkBufferCreateInfo inputBufferParams =
1811 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1812 DE_NULL, // const void* pNext;
1813 0u, // VkBufferCreateFlags flags;
1814 inputBufferSize, // VkDeviceSize size;
1815 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
1816 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1817 1u, // deUint32 queueFamilyCount;
1818 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1821 m_inputBuffer = createBuffer(vk, vkDevice, &inputBufferParams);
1822 m_inputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_inputBuffer), MemoryRequirement::HostVisible);
1824 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_inputBuffer, m_inputAlloc->getMemory(), m_inputAlloc->getOffset()));
1826 const VkBufferCreateInfo outputBufferParams =
1828 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1829 DE_NULL, // const void* pNext;
1830 0u, // VkBufferCreateFlags flags;
1831 outputBufferSize, // VkDeviceSize size;
1832 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
1833 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1834 1u, // deUint32 queueFamilyCount;
1835 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1838 m_outputBuffer = createBuffer(vk, vkDevice, &outputBufferParams);
1839 m_outputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_outputBuffer), MemoryRequirement::HostVisible);
1841 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_outputBuffer, m_outputAlloc->getMemory(), m_outputAlloc->getOffset()));
1844 // ComputeShaderExecutor
1846 class ComputeShaderExecutor : public BufferIoExecutor
1849 ComputeShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1850 virtual ~ComputeShaderExecutor (void);
1852 static void generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
1854 virtual void execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources);
1857 static std::string generateComputeShader (const ShaderSpec& spec);
1860 const VkDescriptorSetLayout m_extraResourcesLayout;
1863 ComputeShaderExecutor::ComputeShaderExecutor(Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1864 : BufferIoExecutor (context, shaderSpec)
1865 , m_extraResourcesLayout (extraResourcesLayout)
1869 ComputeShaderExecutor::~ComputeShaderExecutor (void)
1873 std::string ComputeShaderExecutor::generateComputeShader (const ShaderSpec& spec)
1875 std::ostringstream src;
1876 src << "#version 310 es\n";
1878 if (!spec.globalDeclarations.empty())
1879 src << spec.globalDeclarations << "\n";
1881 src << "layout(local_size_x = 1) in;\n"
1884 declareBufferBlocks(src, spec);
1886 src << "void main (void)\n"
1888 << " uint invocationNdx = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z\n"
1889 << " + gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n";
1891 generateExecBufferIo(src, spec, "invocationNdx");
1898 void ComputeShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1900 programCollection.glslSources.add("compute") << glu::ComputeSource(generateComputeShader(shaderSpec)) << shaderSpec.buildOptions;
1903 void ComputeShaderExecutor::execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources)
1905 const VkDevice vkDevice = m_context.getDevice();
1906 const DeviceInterface& vk = m_context.getDeviceInterface();
1907 const VkQueue queue = m_context.getUniversalQueue();
1908 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1910 DescriptorPoolBuilder descriptorPoolBuilder;
1911 DescriptorSetLayoutBuilder descriptorSetLayoutBuilder;
1913 Move<VkShaderModule> computeShaderModule;
1914 Move<VkPipeline> computePipeline;
1915 Move<VkPipelineLayout> pipelineLayout;
1916 Move<VkCommandPool> cmdPool;
1917 Move<VkDescriptorPool> descriptorPool;
1918 Move<VkDescriptorSetLayout> descriptorSetLayout;
1919 Move<VkDescriptorSet> descriptorSet;
1920 const deUint32 numDescriptorSets = (m_extraResourcesLayout != 0) ? 2u : 1u;
1921 Move<VkFence> fence;
1923 DE_ASSERT((m_extraResourcesLayout != 0) == (extraResources != 0));
1925 initBuffers(numValues);
1927 // Setup input buffer & copy data
1928 uploadInputBuffer(inputs, numValues);
1930 // Create command pool
1931 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1933 // Create command buffer
1934 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1936 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1937 DE_NULL, // const void* pNext;
1938 0u, // VkCmdBufferOptimizeFlags flags;
1939 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1942 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1943 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1944 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1945 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1947 descriptorSetLayout = descriptorSetLayoutBuilder.build(vk, vkDevice);
1948 descriptorPool = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1950 const VkDescriptorSetAllocateInfo allocInfo =
1952 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1956 &*descriptorSetLayout
1959 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
1961 // Create pipeline layout
1963 const VkDescriptorSetLayout descriptorSetLayouts[] =
1965 *descriptorSetLayout,
1966 m_extraResourcesLayout
1968 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1970 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1971 DE_NULL, // const void* pNext;
1972 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
1973 numDescriptorSets, // deUint32 CdescriptorSetCount;
1974 descriptorSetLayouts, // const VkDescriptorSetLayout* pSetLayouts;
1975 0u, // deUint32 pushConstantRangeCount;
1976 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1979 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1984 computeShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("compute"), 0);
1989 const VkPipelineShaderStageCreateInfo shaderStageParams[1] =
1992 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1993 DE_NULL, // const void* pNext;
1994 (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
1995 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagsBit stage;
1996 *computeShaderModule, // VkShaderModule shader;
1997 "main", // const char* pName;
1998 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2002 const VkComputePipelineCreateInfo computePipelineParams =
2004 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
2005 DE_NULL, // const void* pNext;
2006 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
2007 *shaderStageParams, // VkPipelineShaderStageCreateInfo cs;
2008 *pipelineLayout, // VkPipelineLayout layout;
2009 0u, // VkPipeline basePipelineHandle;
2010 0u, // int32_t basePipelineIndex;
2013 computePipeline = createComputePipeline(vk, vkDevice, DE_NULL, &computePipelineParams);
2017 fence = createFence(vk, vkDevice);
2019 const int maxValuesPerInvocation = m_context.getDeviceProperties().limits.maxComputeWorkGroupSize[0];
2021 const deUint32 inputStride = getInputStride();
2022 const deUint32 outputStride = getOutputStride();
2024 while (curOffset < numValues)
2026 Move<VkCommandBuffer> cmdBuffer;
2027 const int numToExec = de::min(maxValuesPerInvocation, numValues-curOffset);
2029 // Update descriptors
2031 DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2033 const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2035 *m_outputBuffer, // VkBuffer buffer;
2036 curOffset * outputStride, // VkDeviceSize offset;
2037 numToExec * outputStride // VkDeviceSize range;
2040 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2044 const VkDescriptorBufferInfo inputDescriptorBufferInfo =
2046 *m_inputBuffer, // VkBuffer buffer;
2047 curOffset * inputStride, // VkDeviceSize offset;
2048 numToExec * inputStride // VkDeviceSize range;
2051 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2054 descriptorSetUpdateBuilder.update(vk, vkDevice);
2057 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2058 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2059 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
2062 const VkDescriptorSet descriptorSets[] = { *descriptorSet, extraResources };
2063 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, numDescriptorSets, descriptorSets, 0u, DE_NULL);
2066 vk.cmdDispatch(*cmdBuffer, numToExec, 1, 1);
2068 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2070 curOffset += numToExec;
2074 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2076 const VkSubmitInfo submitInfo =
2078 VK_STRUCTURE_TYPE_SUBMIT_INFO,
2081 (const VkSemaphore*)DE_NULL,
2082 (const VkPipelineStageFlags*)DE_NULL,
2086 (const VkSemaphore*)DE_NULL,
2089 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2090 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2095 readOutputBuffer(outputs, numValues);
2098 // Tessellation utils
2100 static std::string generateVertexShaderForTess (void)
2102 std::ostringstream src;
2103 src << "#version 310 es\n"
2104 << "void main (void)\n{\n"
2105 << " gl_Position = vec4(gl_VertexIndex/2, gl_VertexIndex%2, 0.0, 1.0);\n"
2111 class TessellationExecutor : public BufferIoExecutor
2114 TessellationExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
2115 virtual ~TessellationExecutor (void);
2117 void renderTess (deUint32 numValues, deUint32 vertexCount, deUint32 patchControlPoints, VkDescriptorSet extraResources);
2120 const VkDescriptorSetLayout m_extraResourcesLayout;
2123 TessellationExecutor::TessellationExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2124 : BufferIoExecutor (context, shaderSpec)
2125 , m_extraResourcesLayout (extraResourcesLayout)
2127 const VkPhysicalDeviceFeatures& features = context.getDeviceFeatures();
2129 if (!features.tessellationShader)
2130 TCU_THROW(NotSupportedError, "Tessellation shader is not supported by device");
2133 TessellationExecutor::~TessellationExecutor (void)
2137 void TessellationExecutor::renderTess (deUint32 numValues, deUint32 vertexCount, deUint32 patchControlPoints, VkDescriptorSet extraResources)
2139 const size_t inputBufferSize = numValues * getInputStride();
2140 const VkDevice vkDevice = m_context.getDevice();
2141 const DeviceInterface& vk = m_context.getDeviceInterface();
2142 const VkQueue queue = m_context.getUniversalQueue();
2143 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2144 Allocator& memAlloc = m_context.getDefaultAllocator();
2146 const tcu::UVec2 renderSize (DEFAULT_RENDER_WIDTH, DEFAULT_RENDER_HEIGHT);
2148 Move<VkImage> colorImage;
2149 de::MovePtr<Allocation> colorImageAlloc;
2150 VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
2151 Move<VkImageView> colorImageView;
2153 Move<VkRenderPass> renderPass;
2154 Move<VkFramebuffer> framebuffer;
2155 Move<VkPipelineLayout> pipelineLayout;
2156 Move<VkPipeline> graphicsPipeline;
2158 Move<VkShaderModule> vertexShaderModule;
2159 Move<VkShaderModule> tessControlShaderModule;
2160 Move<VkShaderModule> tessEvalShaderModule;
2161 Move<VkShaderModule> fragmentShaderModule;
2163 Move<VkCommandPool> cmdPool;
2164 Move<VkCommandBuffer> cmdBuffer;
2166 Move<VkFence> fence;
2168 Move<VkDescriptorPool> descriptorPool;
2169 Move<VkDescriptorSetLayout> descriptorSetLayout;
2170 Move<VkDescriptorSet> descriptorSet;
2171 const deUint32 numDescriptorSets = (m_extraResourcesLayout != 0) ? 2u : 1u;
2173 DE_ASSERT((m_extraResourcesLayout != 0) == (extraResources != 0));
2175 // Create color image
2177 const VkImageCreateInfo colorImageParams =
2179 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2180 DE_NULL, // const void* pNext;
2181 0u, // VkImageCreateFlags flags;
2182 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2183 colorFormat, // VkFormat format;
2184 { renderSize.x(), renderSize.y(), 1u }, // VkExtent3D extent;
2185 1u, // deUint32 mipLevels;
2186 1u, // deUint32 arraySize;
2187 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2188 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2189 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
2190 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2191 1u, // deUint32 queueFamilyCount;
2192 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2193 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
2196 colorImage = createImage(vk, vkDevice, &colorImageParams);
2198 // Allocate and bind color image memory
2199 colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *colorImage), MemoryRequirement::Any);
2200 VK_CHECK(vk.bindImageMemory(vkDevice, *colorImage, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
2203 // Create color attachment view
2205 const VkImageViewCreateInfo colorImageViewParams =
2207 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2208 DE_NULL, // const void* pNext;
2209 0u, // VkImageViewCreateFlags flags;
2210 *colorImage, // VkImage image;
2211 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2212 colorFormat, // VkFormat format;
2214 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
2215 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
2216 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
2217 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
2218 }, // VkComponentsMapping components;
2220 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2221 0u, // deUint32 baseMipLevel;
2222 1u, // deUint32 mipLevels;
2223 0u, // deUint32 baseArraylayer;
2224 1u // deUint32 layerCount;
2225 } // VkImageSubresourceRange subresourceRange;
2228 colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
2231 // Create render pass
2233 const VkAttachmentDescription colorAttachmentDescription =
2235 0u, // VkAttachmentDescriptorFlags flags;
2236 colorFormat, // VkFormat format;
2237 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2238 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
2239 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2240 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2241 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
2242 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2243 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
2246 const VkAttachmentDescription attachments[1] =
2248 colorAttachmentDescription
2251 const VkAttachmentReference colorAttachmentReference =
2253 0u, // deUint32 attachment;
2254 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
2257 const VkSubpassDescription subpassDescription =
2259 0u, // VkSubpassDescriptionFlags flags;
2260 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
2261 0u, // deUint32 inputCount;
2262 DE_NULL, // const VkAttachmentReference* pInputAttachments;
2263 1u, // deUint32 colorCount;
2264 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
2265 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
2266 DE_NULL, // VkAttachmentReference depthStencilAttachment;
2267 0u, // deUint32 preserveCount;
2268 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
2271 const VkRenderPassCreateInfo renderPassParams =
2273 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
2274 DE_NULL, // const void* pNext;
2275 0u, // VkRenderPassCreateFlags flags;
2276 1u, // deUint32 attachmentCount;
2277 attachments, // const VkAttachmentDescription* pAttachments;
2278 1u, // deUint32 subpassCount;
2279 &subpassDescription, // const VkSubpassDescription* pSubpasses;
2280 0u, // deUint32 dependencyCount;
2281 DE_NULL // const VkSubpassDependency* pDependencies;
2284 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
2287 // Create framebuffer
2289 const VkFramebufferCreateInfo framebufferParams =
2291 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
2292 DE_NULL, // const void* pNext;
2293 0u, // VkFramebufferCreateFlags flags;
2294 *renderPass, // VkRenderPass renderPass;
2295 1u, // deUint32 attachmentCount;
2296 &*colorImageView, // const VkAttachmentBindInfo* pAttachments;
2297 (deUint32)renderSize.x(), // deUint32 width;
2298 (deUint32)renderSize.y(), // deUint32 height;
2299 1u // deUint32 layers;
2302 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
2305 // Create descriptors
2307 DescriptorPoolBuilder descriptorPoolBuilder;
2308 DescriptorSetLayoutBuilder descriptorSetLayoutBuilder;
2310 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2311 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2312 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2313 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2315 descriptorSetLayout = descriptorSetLayoutBuilder.build(vk, vkDevice);
2316 descriptorPool = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2318 const VkDescriptorSetAllocateInfo allocInfo =
2320 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2324 &*descriptorSetLayout
2327 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2328 // Update descriptors
2330 DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2331 const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2333 *m_outputBuffer, // VkBuffer buffer;
2334 0u, // VkDeviceSize offset;
2335 VK_WHOLE_SIZE // VkDeviceSize range;
2338 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2340 VkDescriptorBufferInfo inputDescriptorBufferInfo =
2342 0, // VkBuffer buffer;
2343 0u, // VkDeviceSize offset;
2344 VK_WHOLE_SIZE // VkDeviceSize range;
2347 if (inputBufferSize > 0)
2349 inputDescriptorBufferInfo.buffer = *m_inputBuffer;
2351 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2354 descriptorSetUpdateBuilder.update(vk, vkDevice);
2358 // Create pipeline layout
2360 const VkDescriptorSetLayout descriptorSetLayouts[] =
2362 *descriptorSetLayout,
2363 m_extraResourcesLayout
2365 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2367 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
2368 DE_NULL, // const void* pNext;
2369 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
2370 numDescriptorSets, // deUint32 descriptorSetCount;
2371 descriptorSetLayouts, // const VkDescriptorSetLayout* pSetLayouts;
2372 0u, // deUint32 pushConstantRangeCount;
2373 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
2376 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2379 // Create shader modules
2381 vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
2382 tessControlShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tess_control"), 0);
2383 tessEvalShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tess_eval"), 0);
2384 fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
2389 const VkPipelineShaderStageCreateInfo shaderStageParams[4] =
2392 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2393 DE_NULL, // const void* pNext;
2394 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2395 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBit stage;
2396 *vertexShaderModule, // VkShaderModule shader;
2397 "main", // const char* pName;
2398 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2401 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2402 DE_NULL, // const void* pNext;
2403 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2404 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, // VkShaderStageFlagBit stage;
2405 *tessControlShaderModule, // VkShaderModule shader;
2406 "main", // const char* pName;
2407 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2410 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2411 DE_NULL, // const void* pNext;
2412 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2413 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, // VkShaderStageFlagBit stage;
2414 *tessEvalShaderModule, // VkShaderModule shader;
2415 "main", // const char* pName;
2416 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2419 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2420 DE_NULL, // const void* pNext;
2421 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2422 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBit stage;
2423 *fragmentShaderModule, // VkShaderModule shader;
2424 "main", // const char* pName;
2425 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2429 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
2431 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
2432 DE_NULL, // const void* pNext;
2433 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
2434 0u, // deUint32 bindingCount;
2435 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
2436 0u, // deUint32 attributeCount;
2437 DE_NULL, // const VkVertexInputAttributeDescription* pvertexAttributeDescriptions;
2440 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
2442 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
2443 DE_NULL, // const void* pNext;
2444 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2445 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, // VkPrimitiveTopology topology;
2446 DE_FALSE // VkBool32 primitiveRestartEnable;
2449 struct VkPipelineTessellationStateCreateInfo tessellationStateParams =
2451 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
2452 DE_NULL, // const void* pNext;
2453 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags;
2454 patchControlPoints // uint32_t patchControlPoints;
2457 const VkViewport viewport =
2459 0.0f, // float originX;
2460 0.0f, // float originY;
2461 (float)renderSize.x(), // float width;
2462 (float)renderSize.y(), // float height;
2463 0.0f, // float minDepth;
2464 1.0f // float maxDepth;
2467 const VkRect2D scissor =
2472 }, // VkOffset2D offset;
2474 renderSize.x(), // deUint32 width;
2475 renderSize.y(), // deUint32 height;
2476 }, // VkExtent2D extent;
2479 const VkPipelineViewportStateCreateInfo viewportStateParams =
2481 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
2482 DE_NULL, // const void* pNext;
2483 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewPortStateCreateFlags flags;
2484 1u, // deUint32 viewportCount;
2485 &viewport, // const VkViewport* pViewports;
2486 1u, // deUint32 scissorsCount;
2487 &scissor // const VkRect2D* pScissors;
2490 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
2492 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
2493 DE_NULL, // const void* pNext;
2494 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStageCreateFlags flags;
2495 VK_FALSE, // VkBool32 depthClipEnable;
2496 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
2497 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
2498 VK_CULL_MODE_NONE, // VkCullMode cullMode;
2499 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
2500 VK_FALSE, // VkBool32 depthBiasEnable;
2501 0.0f, // float depthBias;
2502 0.0f, // float depthBiasClamp;
2503 0.0f, // float slopeScaledDepthBias;
2504 1.0f // float lineWidth;
2507 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
2509 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
2510 DE_NULL, // const void* pNext;
2511 0u, // VkPipelineMultisampleStateCreateFlags flags;
2512 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
2513 VK_FALSE, // VkBool32 sampleShadingEnable;
2514 0.0f, // float minSampleShading;
2515 DE_NULL, // const VkSampleMask* pSampleMask;
2516 VK_FALSE, // VkBool32 alphaToCoverageEnable;
2517 VK_FALSE // VkBool32 alphaToOneEnable;
2520 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
2522 VK_FALSE, // VkBool32 blendEnable;
2523 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcBlendColor;
2524 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destBlendColor;
2525 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
2526 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcBlendAlpha;
2527 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destBlendAlpha;
2528 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
2529 (VK_COLOR_COMPONENT_R_BIT |
2530 VK_COLOR_COMPONENT_G_BIT |
2531 VK_COLOR_COMPONENT_B_BIT |
2532 VK_COLOR_COMPONENT_A_BIT) // VkColorComponentFlags colorWriteMask;
2535 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
2537 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
2538 DE_NULL, // const void* pNext;
2539 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags
2540 VK_FALSE, // VkBool32 logicOpEnable;
2541 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
2542 1u, // deUint32 attachmentCount;
2543 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
2544 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConst[4];
2547 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
2549 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
2550 DE_NULL, // const void* pNext;
2551 0u, // VkPipelineCreateFlags flags;
2552 4u, // deUint32 stageCount;
2553 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages;
2554 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
2555 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
2556 &tessellationStateParams, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
2557 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
2558 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
2559 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
2560 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
2561 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
2562 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
2563 *pipelineLayout, // VkPipelineLayout layout;
2564 *renderPass, // VkRenderPass renderPass;
2565 0u, // deUint32 subpass;
2566 0u, // VkPipeline basePipelineHandle;
2567 0u // deInt32 basePipelineIndex;
2570 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
2573 // Create command pool
2574 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
2576 // Create command buffer
2578 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
2580 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
2581 DE_NULL, // const void* pNext;
2582 0u, // VkCmdBufferOptimizeFlags flags;
2583 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2586 const VkClearValue clearValues[1] =
2588 getDefaultClearColor()
2591 const VkRenderPassBeginInfo renderPassBeginInfo =
2593 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
2594 DE_NULL, // const void* pNext;
2595 *renderPass, // VkRenderPass renderPass;
2596 *framebuffer, // VkFramebuffer framebuffer;
2597 { { 0, 0 }, { renderSize.x(), renderSize.y() } }, // VkRect2D renderArea;
2598 1, // deUint32 attachmentCount;
2599 clearValues // const VkClearValue* pClearValues;
2602 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2604 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2606 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2608 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
2611 const VkDescriptorSet descriptorSets[] = { *descriptorSet, extraResources };
2612 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, numDescriptorSets, descriptorSets, 0u, DE_NULL);
2615 vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
2617 vk.cmdEndRenderPass(*cmdBuffer);
2618 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2622 fence = createFence(vk, vkDevice);
2626 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2627 const VkSubmitInfo submitInfo =
2629 VK_STRUCTURE_TYPE_SUBMIT_INFO,
2632 (const VkSemaphore*)0,
2633 (const VkPipelineStageFlags*)DE_NULL,
2637 (const VkSemaphore*)0,
2639 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2640 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2644 // TessControlExecutor
2646 class TessControlExecutor : public TessellationExecutor
2649 TessControlExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
2650 virtual ~TessControlExecutor (void);
2652 static void generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
2654 virtual void execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources);
2657 static std::string generateTessControlShader (const ShaderSpec& shaderSpec);
2660 TessControlExecutor::TessControlExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2661 : TessellationExecutor(context, shaderSpec, extraResourcesLayout)
2665 TessControlExecutor::~TessControlExecutor (void)
2669 std::string TessControlExecutor::generateTessControlShader (const ShaderSpec& shaderSpec)
2671 std::ostringstream src;
2672 src << "#version 310 es\n"
2673 "#extension GL_EXT_tessellation_shader : require\n\n";
2675 if (!shaderSpec.globalDeclarations.empty())
2676 src << shaderSpec.globalDeclarations << "\n";
2678 src << "\nlayout(vertices = 1) out;\n\n";
2680 declareBufferBlocks(src, shaderSpec);
2682 src << "void main (void)\n{\n";
2684 for (int ndx = 0; ndx < 2; ndx++)
2685 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2687 for (int ndx = 0; ndx < 4; ndx++)
2688 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2691 << "\thighp uint invocationId = uint(gl_PrimitiveID);\n";
2693 generateExecBufferIo(src, shaderSpec, "invocationId");
2700 static std::string generateEmptyTessEvalShader ()
2702 std::ostringstream src;
2704 src << "#version 310 es\n"
2705 "#extension GL_EXT_tessellation_shader : require\n\n";
2707 src << "layout(triangles, ccw) in;\n";
2709 src << "\nvoid main (void)\n{\n"
2710 << "\tgl_Position = vec4(gl_TessCoord.xy, 0.0, 1.0);\n"
2716 void TessControlExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
2718 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess()) << shaderSpec.buildOptions;
2719 programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generateTessControlShader(shaderSpec)) << shaderSpec.buildOptions;
2720 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateEmptyTessEvalShader()) << shaderSpec.buildOptions;
2721 programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource()) << shaderSpec.buildOptions;
2724 void TessControlExecutor::execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources)
2726 const deUint32 patchSize = 3;
2728 initBuffers(numValues);
2730 // Setup input buffer & copy data
2731 uploadInputBuffer(inputs, numValues);
2733 renderTess(numValues, patchSize * numValues, patchSize, extraResources);
2736 readOutputBuffer(outputs, numValues);
2739 // TessEvaluationExecutor
2741 class TessEvaluationExecutor : public TessellationExecutor
2744 TessEvaluationExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
2745 virtual ~TessEvaluationExecutor (void);
2747 static void generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
2749 virtual void execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources);
2752 static std::string generateTessEvalShader (const ShaderSpec& shaderSpec);
2755 TessEvaluationExecutor::TessEvaluationExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2756 : TessellationExecutor (context, shaderSpec, extraResourcesLayout)
2760 TessEvaluationExecutor::~TessEvaluationExecutor (void)
2764 static std::string generatePassthroughTessControlShader (void)
2766 std::ostringstream src;
2768 src << "#version 310 es\n"
2769 "#extension GL_EXT_tessellation_shader : require\n\n";
2771 src << "layout(vertices = 1) out;\n\n";
2773 src << "void main (void)\n{\n";
2775 for (int ndx = 0; ndx < 2; ndx++)
2776 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2778 for (int ndx = 0; ndx < 4; ndx++)
2779 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2786 std::string TessEvaluationExecutor::generateTessEvalShader (const ShaderSpec& shaderSpec)
2788 std::ostringstream src;
2790 src << "#version 310 es\n"
2791 "#extension GL_EXT_tessellation_shader : require\n\n";
2793 if (!shaderSpec.globalDeclarations.empty())
2794 src << shaderSpec.globalDeclarations << "\n";
2798 src << "layout(isolines, equal_spacing) in;\n\n";
2800 declareBufferBlocks(src, shaderSpec);
2802 src << "void main (void)\n{\n"
2803 << "\tgl_Position = vec4(gl_TessCoord.x, 0.0, 0.0, 1.0);\n"
2804 << "\thighp uint invocationId = uint(gl_PrimitiveID)*2u + (gl_TessCoord.x > 0.5 ? 1u : 0u);\n";
2806 generateExecBufferIo(src, shaderSpec, "invocationId");
2813 void TessEvaluationExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
2815 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess()) << shaderSpec.buildOptions;
2816 programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generatePassthroughTessControlShader()) << shaderSpec.buildOptions;
2817 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateTessEvalShader(shaderSpec)) << shaderSpec.buildOptions;
2818 programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource()) << shaderSpec.buildOptions;
2821 void TessEvaluationExecutor::execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources)
2823 const int patchSize = 2;
2824 const int alignedValues = deAlign32(numValues, patchSize);
2826 // Initialize buffers with aligned value count to make room for padding
2827 initBuffers(alignedValues);
2829 // Setup input buffer & copy data
2830 uploadInputBuffer(inputs, numValues);
2832 renderTess((deUint32)alignedValues, (deUint32)alignedValues, (deUint32)patchSize, extraResources);
2835 readOutputBuffer(outputs, numValues);
2842 ShaderExecutor::~ShaderExecutor (void)
2848 void generateSources (glu::ShaderType shaderType, const ShaderSpec& shaderSpec, vk::SourceCollections& dst)
2852 case glu::SHADERTYPE_VERTEX: VertexShaderExecutor::generateSources (shaderSpec, dst); break;
2853 case glu::SHADERTYPE_TESSELLATION_CONTROL: TessControlExecutor::generateSources (shaderSpec, dst); break;
2854 case glu::SHADERTYPE_TESSELLATION_EVALUATION: TessEvaluationExecutor::generateSources (shaderSpec, dst); break;
2855 case glu::SHADERTYPE_GEOMETRY: GeometryShaderExecutor::generateSources (shaderSpec, dst); break;
2856 case glu::SHADERTYPE_FRAGMENT: FragmentShaderExecutor::generateSources (shaderSpec, dst); break;
2857 case glu::SHADERTYPE_COMPUTE: ComputeShaderExecutor::generateSources (shaderSpec, dst); break;
2859 TCU_THROW(InternalError, "Unsupported shader type");
2863 ShaderExecutor* createExecutor (Context& context, glu::ShaderType shaderType, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2867 case glu::SHADERTYPE_VERTEX: return new VertexShaderExecutor (context, shaderSpec, extraResourcesLayout);
2868 case glu::SHADERTYPE_TESSELLATION_CONTROL: return new TessControlExecutor (context, shaderSpec, extraResourcesLayout);
2869 case glu::SHADERTYPE_TESSELLATION_EVALUATION: return new TessEvaluationExecutor (context, shaderSpec, extraResourcesLayout);
2870 case glu::SHADERTYPE_GEOMETRY: return new GeometryShaderExecutor (context, shaderSpec, extraResourcesLayout);
2871 case glu::SHADERTYPE_FRAGMENT: return new FragmentShaderExecutor (context, shaderSpec, extraResourcesLayout);
2872 case glu::SHADERTYPE_COMPUTE: return new ComputeShaderExecutor (context, shaderSpec, extraResourcesLayout);
2874 TCU_THROW(InternalError, "Unsupported shader type");