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 << glu::getGLSLVersionDeclaration(shaderSpec.glslVersion) << "\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 << glu::getGLSLVersionDeclaration(shaderSpec.glslVersion) << "\n";
324 if (shaderSpec.glslVersion == glu::GLSL_VERSION_310_ES)
325 src << "#extension GL_EXT_geometry_shader : require\n";
327 if (!shaderSpec.globalDeclarations.empty())
328 src << shaderSpec.globalDeclarations << "\n";
330 src << "layout(points) in;\n"
331 << "layout(points, max_vertices = 1) out;\n";
333 int locationNumber = 0;
334 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber)
335 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(input->varType, inputPrefix + input->name) << "[];\n";
338 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber)
340 DE_ASSERT(output->varType.isBasicType());
342 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
344 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
345 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
346 const glu::VarType intType (intBaseType, glu::PRECISION_HIGHP);
348 src << "layout(location = " << locationNumber << ") flat out " << glu::declare(intType, outputPrefix + output->name) << ";\n";
351 src << "layout(location = " << locationNumber << ") flat out " << glu::declare(output->varType, outputPrefix + output->name) << ";\n";
355 << "void main (void)\n"
357 << " gl_Position = gl_in[0].gl_Position;\n\n";
359 // Fetch input variables
360 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input)
361 src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << "[0];\n";
363 // Declare local output variables.
364 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
365 src << "\t" << glu::declare(output->varType, output->name) << ";\n";
369 // Operation - indented to correct level.
371 std::istringstream opSrc (shaderSpec.source);
374 while (std::getline(opSrc, line))
375 src << "\t" << line << "\n";
378 // Assignments to outputs.
379 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
381 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
383 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
384 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
386 src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << output->name << ");\n";
389 src << "\t" << outputPrefix << output->name << " = " << output->name << ";\n";
392 src << " EmitVertex();\n"
393 << " EndPrimitive();\n"
399 static std::string generateFragmentShader (const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& inputPrefix, const std::string& outputPrefix)
401 std::ostringstream src;
402 src << glu::getGLSLVersionDeclaration(shaderSpec.glslVersion) << "\n";
403 if (!shaderSpec.globalDeclarations.empty())
404 src << shaderSpec.globalDeclarations << "\n";
406 int locationNumber = 0;
407 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber)
408 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n";
410 generateFragShaderOutputDecl(src, shaderSpec, useIntOutputs, outLocationMap, outputPrefix);
412 src << "\nvoid main (void)\n{\n";
414 // Declare & fetch local input variables
415 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input)
416 src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << ";\n";
418 // Declare output variables
419 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
420 src << "\t" << glu::declare(output->varType, output->name) << ";\n";
422 // Operation - indented to correct level.
424 std::istringstream opSrc (shaderSpec.source);
427 while (std::getline(opSrc, line))
428 src << "\t" << line << "\n";
431 generateFragShaderOutAssign(src, shaderSpec, useIntOutputs, "", outputPrefix);
438 // FragmentOutExecutor
440 class FragmentOutExecutor : public ShaderExecutor
443 FragmentOutExecutor (Context& context, glu::ShaderType shaderType, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
444 virtual ~FragmentOutExecutor (void);
446 virtual void execute (int numValues,
447 const void* const* inputs,
448 void* const* outputs,
449 VkDescriptorSet extraResources);
452 const glu::ShaderType m_shaderType;
453 const FragmentOutputLayout m_outputLayout;
456 void bindAttributes (int numValues,
457 const void* const* inputs);
459 void addAttribute (deUint32 bindingLocation,
461 deUint32 sizePerElement,
463 const void* dataPtr);
464 // reinit render data members
465 virtual void clearRenderData (void);
467 const VkDescriptorSetLayout m_extraResourcesLayout;
469 std::vector<VkVertexInputBindingDescription> m_vertexBindingDescriptions;
470 std::vector<VkVertexInputAttributeDescription> m_vertexAttributeDescriptions;
471 std::vector<VkBufferSp> m_vertexBuffers;
472 std::vector<AllocationSp> m_vertexBufferAllocs;
475 static FragmentOutputLayout computeFragmentOutputLayout (const std::vector<Symbol>& symbols)
477 FragmentOutputLayout ret;
480 for (std::vector<Symbol>::const_iterator it = symbols.begin(); it != symbols.end(); ++it)
482 const int numLocations = glu::getDataTypeNumLocations(it->varType.getBasicType());
484 TCU_CHECK_INTERNAL(!de::contains(ret.locationMap, it->name));
485 de::insert(ret.locationMap, it->name, location);
486 location += numLocations;
488 for (int ndx = 0; ndx < numLocations; ++ndx)
489 ret.locationSymbols.push_back(&*it);
495 FragmentOutExecutor::FragmentOutExecutor (Context& context, glu::ShaderType shaderType, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
496 : ShaderExecutor (context, shaderSpec)
497 , m_shaderType (shaderType)
498 , m_outputLayout (computeFragmentOutputLayout(m_shaderSpec.outputs))
499 , m_extraResourcesLayout (extraResourcesLayout)
503 FragmentOutExecutor::~FragmentOutExecutor (void)
507 static std::vector<tcu::Vec2> computeVertexPositions (int numValues, const tcu::IVec2& renderSize)
509 std::vector<tcu::Vec2> positions(numValues);
510 for (int valNdx = 0; valNdx < numValues; valNdx++)
512 const int ix = valNdx % renderSize.x();
513 const int iy = valNdx / renderSize.x();
514 const float fx = -1.0f + 2.0f*((float(ix) + 0.5f) / float(renderSize.x()));
515 const float fy = -1.0f + 2.0f*((float(iy) + 0.5f) / float(renderSize.y()));
517 positions[valNdx] = tcu::Vec2(fx, fy);
523 static tcu::TextureFormat getRenderbufferFormatForOutput (const glu::VarType& outputType, bool useIntOutputs)
525 const tcu::TextureFormat::ChannelOrder channelOrderMap[] =
527 tcu::TextureFormat::R,
528 tcu::TextureFormat::RG,
529 tcu::TextureFormat::RGBA, // No RGB variants available.
530 tcu::TextureFormat::RGBA
533 const glu::DataType basicType = outputType.getBasicType();
534 const int numComps = glu::getDataTypeNumComponents(basicType);
535 tcu::TextureFormat::ChannelType channelType;
537 switch (glu::getDataTypeScalarType(basicType))
539 case glu::TYPE_UINT: channelType = tcu::TextureFormat::UNSIGNED_INT32; break;
540 case glu::TYPE_INT: channelType = tcu::TextureFormat::SIGNED_INT32; break;
541 case glu::TYPE_BOOL: channelType = tcu::TextureFormat::SIGNED_INT32; break;
542 case glu::TYPE_FLOAT: channelType = useIntOutputs ? tcu::TextureFormat::UNSIGNED_INT32 : tcu::TextureFormat::FLOAT; break;
544 throw tcu::InternalError("Invalid output type");
547 DE_ASSERT(de::inRange<int>(numComps, 1, DE_LENGTH_OF_ARRAY(channelOrderMap)));
549 return tcu::TextureFormat(channelOrderMap[numComps-1], channelType);
552 static VkFormat getAttributeFormat (const glu::DataType dataType)
556 case glu::TYPE_FLOAT: return VK_FORMAT_R32_SFLOAT;
557 case glu::TYPE_FLOAT_VEC2: return VK_FORMAT_R32G32_SFLOAT;
558 case glu::TYPE_FLOAT_VEC3: return VK_FORMAT_R32G32B32_SFLOAT;
559 case glu::TYPE_FLOAT_VEC4: return VK_FORMAT_R32G32B32A32_SFLOAT;
561 case glu::TYPE_INT: return VK_FORMAT_R32_SINT;
562 case glu::TYPE_INT_VEC2: return VK_FORMAT_R32G32_SINT;
563 case glu::TYPE_INT_VEC3: return VK_FORMAT_R32G32B32_SINT;
564 case glu::TYPE_INT_VEC4: return VK_FORMAT_R32G32B32A32_SINT;
566 case glu::TYPE_UINT: return VK_FORMAT_R32_UINT;
567 case glu::TYPE_UINT_VEC2: return VK_FORMAT_R32G32_UINT;
568 case glu::TYPE_UINT_VEC3: return VK_FORMAT_R32G32B32_UINT;
569 case glu::TYPE_UINT_VEC4: return VK_FORMAT_R32G32B32A32_UINT;
571 case glu::TYPE_FLOAT_MAT2: return VK_FORMAT_R32G32_SFLOAT;
572 case glu::TYPE_FLOAT_MAT2X3: return VK_FORMAT_R32G32B32_SFLOAT;
573 case glu::TYPE_FLOAT_MAT2X4: return VK_FORMAT_R32G32B32A32_SFLOAT;
574 case glu::TYPE_FLOAT_MAT3X2: return VK_FORMAT_R32G32_SFLOAT;
575 case glu::TYPE_FLOAT_MAT3: return VK_FORMAT_R32G32B32_SFLOAT;
576 case glu::TYPE_FLOAT_MAT3X4: return VK_FORMAT_R32G32B32A32_SFLOAT;
577 case glu::TYPE_FLOAT_MAT4X2: return VK_FORMAT_R32G32_SFLOAT;
578 case glu::TYPE_FLOAT_MAT4X3: return VK_FORMAT_R32G32B32_SFLOAT;
579 case glu::TYPE_FLOAT_MAT4: return VK_FORMAT_R32G32B32A32_SFLOAT;
582 return VK_FORMAT_UNDEFINED;
586 void FragmentOutExecutor::addAttribute (deUint32 bindingLocation, VkFormat format, deUint32 sizePerElement, deUint32 count, const void* dataPtr)
588 // Add binding specification
589 const deUint32 binding = (deUint32)m_vertexBindingDescriptions.size();
590 const VkVertexInputBindingDescription bindingDescription =
594 VK_VERTEX_INPUT_RATE_VERTEX
597 m_vertexBindingDescriptions.push_back(bindingDescription);
599 // Add location and format specification
600 const VkVertexInputAttributeDescription attributeDescription =
602 bindingLocation, // deUint32 location;
603 binding, // deUint32 binding;
604 format, // VkFormat format;
605 0u, // deUint32 offsetInBytes;
608 m_vertexAttributeDescriptions.push_back(attributeDescription);
610 // Upload data to buffer
611 const VkDevice vkDevice = m_context.getDevice();
612 const DeviceInterface& vk = m_context.getDeviceInterface();
613 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
615 const VkDeviceSize inputSize = sizePerElement * count;
616 const VkBufferCreateInfo vertexBufferParams =
618 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
619 DE_NULL, // const void* pNext;
620 0u, // VkBufferCreateFlags flags;
621 inputSize, // VkDeviceSize size;
622 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
623 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
624 1u, // deUint32 queueFamilyCount;
625 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
628 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &vertexBufferParams);
629 de::MovePtr<Allocation> alloc = m_context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
631 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
633 deMemcpy(alloc->getHostPtr(), dataPtr, (size_t)inputSize);
634 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), inputSize);
636 m_vertexBuffers.push_back(de::SharedPtr<Unique<VkBuffer> >(new Unique<VkBuffer>(buffer)));
637 m_vertexBufferAllocs.push_back(AllocationSp(alloc.release()));
640 void FragmentOutExecutor::bindAttributes (int numValues, const void* const* inputs)
643 for (int inputNdx = 0; inputNdx < (int)m_shaderSpec.inputs.size(); inputNdx++)
645 const Symbol& symbol = m_shaderSpec.inputs[inputNdx];
646 const void* ptr = inputs[inputNdx];
647 const glu::DataType basicType = symbol.varType.getBasicType();
648 const int vecSize = glu::getDataTypeScalarSize(basicType);
649 const VkFormat format = getAttributeFormat(basicType);
651 int numAttrsToAdd = 1;
653 if (glu::isDataTypeFloatOrVec(basicType))
654 elementSize = sizeof(float);
655 else if (glu::isDataTypeIntOrIVec(basicType))
656 elementSize = sizeof(int);
657 else if (glu::isDataTypeUintOrUVec(basicType))
658 elementSize = sizeof(deUint32);
659 else if (glu::isDataTypeMatrix(basicType))
661 int numRows = glu::getDataTypeMatrixNumRows(basicType);
662 int numCols = glu::getDataTypeMatrixNumColumns(basicType);
664 elementSize = numRows * numCols * (int)sizeof(float);
665 numAttrsToAdd = numCols;
670 // add attributes, in case of matrix every column is binded as an attribute
671 for (int attrNdx = 0; attrNdx < numAttrsToAdd; attrNdx++)
673 addAttribute((deUint32)m_vertexBindingDescriptions.size(), format, elementSize * vecSize, numValues, ptr);
678 void FragmentOutExecutor::clearRenderData (void)
680 m_vertexBindingDescriptions.clear();
681 m_vertexAttributeDescriptions.clear();
682 m_vertexBuffers.clear();
683 m_vertexBufferAllocs.clear();
686 static Move<VkDescriptorSetLayout> createEmptyDescriptorSetLayout (const DeviceInterface& vkd, VkDevice device)
688 const VkDescriptorSetLayoutCreateInfo createInfo =
690 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
692 (VkDescriptorSetLayoutCreateFlags)0,
696 return createDescriptorSetLayout(vkd, device, &createInfo);
699 static Move<VkDescriptorPool> createDummyDescriptorPool (const DeviceInterface& vkd, VkDevice device)
701 const VkDescriptorPoolSize dummySize =
703 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
706 const VkDescriptorPoolCreateInfo createInfo =
708 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
710 (VkDescriptorPoolCreateFlags)VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
715 return createDescriptorPool(vkd, device, &createInfo);
718 static Move<VkDescriptorSet> allocateSingleDescriptorSet (const DeviceInterface& vkd, VkDevice device, VkDescriptorPool pool, VkDescriptorSetLayout layout)
720 const VkDescriptorSetAllocateInfo allocInfo =
722 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
728 return allocateDescriptorSet(vkd, device, &allocInfo);
731 void FragmentOutExecutor::execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources)
733 const VkDevice vkDevice = m_context.getDevice();
734 const DeviceInterface& vk = m_context.getDeviceInterface();
735 const VkQueue queue = m_context.getUniversalQueue();
736 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
737 Allocator& memAlloc = m_context.getDefaultAllocator();
739 const deUint32 renderSizeX = de::min(static_cast<deUint32>(DEFAULT_RENDER_WIDTH), (deUint32)numValues);
740 const deUint32 renderSizeY = ((deUint32)numValues / renderSizeX) + (((deUint32)numValues % renderSizeX != 0) ? 1u : 0u);
741 const tcu::UVec2 renderSize (renderSizeX, renderSizeY);
742 std::vector<tcu::Vec2> positions;
744 const bool useGeometryShader = m_shaderType == glu::SHADERTYPE_GEOMETRY;
746 std::vector<VkImageSp> colorImages;
747 std::vector<VkImageMemoryBarrier> colorImagePreRenderBarriers;
748 std::vector<VkImageMemoryBarrier> colorImagePostRenderBarriers;
749 std::vector<AllocationSp> colorImageAllocs;
750 std::vector<VkAttachmentDescription> attachments;
751 std::vector<VkClearValue> attachmentClearValues;
752 std::vector<VkImageViewSp> colorImageViews;
754 std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentStates;
755 std::vector<VkAttachmentReference> colorAttachmentReferences;
757 Move<VkRenderPass> renderPass;
758 Move<VkFramebuffer> framebuffer;
759 Move<VkPipelineLayout> pipelineLayout;
760 Move<VkPipeline> graphicsPipeline;
762 Move<VkShaderModule> vertexShaderModule;
763 Move<VkShaderModule> geometryShaderModule;
764 Move<VkShaderModule> fragmentShaderModule;
766 Move<VkCommandPool> cmdPool;
767 Move<VkCommandBuffer> cmdBuffer;
771 Unique<VkDescriptorSetLayout> emptyDescriptorSetLayout (createEmptyDescriptorSetLayout(vk, vkDevice));
772 Unique<VkDescriptorPool> dummyDescriptorPool (createDummyDescriptorPool(vk, vkDevice));
773 Unique<VkDescriptorSet> emptyDescriptorSet (allocateSingleDescriptorSet(vk, vkDevice, *dummyDescriptorPool, *emptyDescriptorSetLayout));
777 // Compute positions - 1px points are used to drive fragment shading.
778 positions = computeVertexPositions(numValues, renderSize.cast<int>());
781 addAttribute(0u, VK_FORMAT_R32G32_SFLOAT, sizeof(tcu::Vec2), (deUint32)positions.size(), &positions[0]);
782 bindAttributes(numValues, inputs);
784 // Create color images
786 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
788 VK_FALSE, // VkBool32 blendEnable;
789 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
790 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
791 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
792 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
793 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destAlphaBlendFactor;
794 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
795 (VK_COLOR_COMPONENT_R_BIT |
796 VK_COLOR_COMPONENT_G_BIT |
797 VK_COLOR_COMPONENT_B_BIT |
798 VK_COLOR_COMPONENT_A_BIT) // VkColorComponentFlags colorWriteMask;
801 for (int outNdx = 0; outNdx < (int)m_outputLayout.locationSymbols.size(); ++outNdx)
803 const bool isFloat = isDataTypeFloatOrVec(m_shaderSpec.outputs[outNdx].varType.getBasicType());
804 const bool isSigned = isDataTypeIntOrIVec (m_shaderSpec.outputs[outNdx].varType.getBasicType());
805 const bool isBool = isDataTypeBoolOrBVec(m_shaderSpec.outputs[outNdx].varType.getBasicType());
806 const VkFormat colorFormat = isFloat ? VK_FORMAT_R32G32B32A32_SFLOAT : (isSigned || isBool ? VK_FORMAT_R32G32B32A32_SINT : VK_FORMAT_R32G32B32A32_UINT);
808 const VkImageCreateInfo colorImageParams =
810 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
811 DE_NULL, // const void* pNext;
812 0u, // VkImageCreateFlags flags;
813 VK_IMAGE_TYPE_2D, // VkImageType imageType;
814 colorFormat, // VkFormat format;
815 { renderSize.x(), renderSize.y(), 1u }, // VkExtent3D extent;
816 1u, // deUint32 mipLevels;
817 1u, // deUint32 arraySize;
818 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
819 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
820 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
821 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
822 1u, // deUint32 queueFamilyCount;
823 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
824 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
827 const VkAttachmentDescription colorAttachmentDescription =
829 0u, // VkAttachmentDescriptorFlags flags;
830 colorFormat, // VkFormat format;
831 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
832 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
833 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
834 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
835 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
836 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
837 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
840 Move<VkImage> colorImage = createImage(vk, vkDevice, &colorImageParams);
841 colorImages.push_back(de::SharedPtr<Unique<VkImage> >(new Unique<VkImage>(colorImage)));
842 attachmentClearValues.push_back(getDefaultClearColor());
844 // Allocate and bind color image memory
846 de::MovePtr<Allocation> colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *((const VkImage*) colorImages.back().get())), MemoryRequirement::Any);
847 VK_CHECK(vk.bindImageMemory(vkDevice, colorImages.back().get()->get(), colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
848 colorImageAllocs.push_back(de::SharedPtr<Allocation>(colorImageAlloc.release()));
850 attachments.push_back(colorAttachmentDescription);
851 colorBlendAttachmentStates.push_back(colorBlendAttachmentState);
853 const VkAttachmentReference colorAttachmentReference =
855 (deUint32) (colorImages.size() - 1), // deUint32 attachment;
856 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
859 colorAttachmentReferences.push_back(colorAttachmentReference);
862 // Create color attachment view
864 const VkImageViewCreateInfo colorImageViewParams =
866 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
867 DE_NULL, // const void* pNext;
868 0u, // VkImageViewCreateFlags flags;
869 colorImages.back().get()->get(), // VkImage image;
870 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
871 colorFormat, // VkFormat format;
873 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
874 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
875 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
876 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
877 }, // VkComponentMapping components;
879 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
880 0u, // deUint32 baseMipLevel;
881 1u, // deUint32 mipLevels;
882 0u, // deUint32 baseArraySlice;
883 1u // deUint32 arraySize;
884 } // VkImageSubresourceRange subresourceRange;
887 Move<VkImageView> colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
888 colorImageViews.push_back(de::SharedPtr<Unique<VkImageView> >(new Unique<VkImageView>(colorImageView)));
890 const VkImageMemoryBarrier colorImagePreRenderBarrier =
892 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
895 (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
896 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), // dstAccessMask
897 VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
898 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
899 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
900 VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex
901 colorImages.back().get()->get(), // image
903 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
906 0u, // baseArrayLayer
908 } // subresourceRange
910 colorImagePreRenderBarriers.push_back(colorImagePreRenderBarrier);
912 const VkImageMemoryBarrier colorImagePostRenderBarrier =
914 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
916 (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
917 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), // srcAccessMask
918 VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask
919 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout
920 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
921 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
922 VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex
923 colorImages.back().get()->get(), // image
925 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
928 0u, // baseArrayLayer
930 } // subresourceRange
932 colorImagePostRenderBarriers.push_back(colorImagePostRenderBarrier);
937 // Create render pass
939 const VkSubpassDescription subpassDescription =
941 0u, // VkSubpassDescriptionFlags flags;
942 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
943 0u, // deUint32 inputCount;
944 DE_NULL, // const VkAttachmentReference* pInputAttachments;
945 (deUint32)colorImages.size(), // deUint32 colorCount;
946 &colorAttachmentReferences[0], // const VkAttachmentReference* colorAttachments;
947 DE_NULL, // const VkAttachmentReference* resolveAttachments;
948 DE_NULL, // VkAttachmentReference depthStencilAttachment;
949 0u, // deUint32 preserveCount;
950 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
953 const VkRenderPassCreateInfo renderPassParams =
955 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
956 DE_NULL, // const void* pNext;
957 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
958 (deUint32)attachments.size(), // deUint32 attachmentCount;
959 &attachments[0], // const VkAttachmentDescription* pAttachments;
960 1u, // deUint32 subpassCount;
961 &subpassDescription, // const VkSubpassDescription* pSubpasses;
962 0u, // deUint32 dependencyCount;
963 DE_NULL // const VkSubpassDependency* pDependencies;
966 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
969 // Create framebuffer
971 std::vector<VkImageView> views(colorImageViews.size());
972 for (size_t i = 0; i < colorImageViews.size(); i++)
974 views[i] = colorImageViews[i].get()->get();
977 const VkFramebufferCreateInfo framebufferParams =
979 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
980 DE_NULL, // const void* pNext;
981 0u, // VkFramebufferCreateFlags flags;
982 *renderPass, // VkRenderPass renderPass;
983 (deUint32)views.size(), // deUint32 attachmentCount;
984 &views[0], // const VkImageView* pAttachments;
985 (deUint32)renderSize.x(), // deUint32 width;
986 (deUint32)renderSize.y(), // deUint32 height;
987 1u // deUint32 layers;
990 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
993 // Create pipeline layout
995 const VkDescriptorSetLayout setLayouts[] =
997 *emptyDescriptorSetLayout,
998 m_extraResourcesLayout
1000 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1002 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1003 DE_NULL, // const void* pNext;
1004 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
1005 (m_extraResourcesLayout != 0 ? 2u : 0u), // deUint32 descriptorSetCount;
1006 setLayouts, // const VkDescriptorSetLayout* pSetLayouts;
1007 0u, // deUint32 pushConstantRangeCount;
1008 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1011 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1016 vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
1017 fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
1019 if (useGeometryShader)
1021 geometryShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("geom"), 0);
1027 std::vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
1029 const VkPipelineShaderStageCreateInfo vertexShaderStageParams =
1031 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1032 DE_NULL, // const void* pNext;
1033 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
1034 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
1035 *vertexShaderModule, // VkShaderModule module;
1036 "main", // const char* pName;
1037 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1040 const VkPipelineShaderStageCreateInfo fragmentShaderStageParams =
1042 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1043 DE_NULL, // const void* pNext;
1044 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
1045 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
1046 *fragmentShaderModule, // VkShaderModule module;
1047 "main", // const char* pName;
1048 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1051 shaderStageParams.push_back(vertexShaderStageParams);
1052 shaderStageParams.push_back(fragmentShaderStageParams);
1054 if (useGeometryShader)
1056 const VkPipelineShaderStageCreateInfo geometryShaderStageParams =
1058 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1059 DE_NULL, // const void* pNext;
1060 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
1061 VK_SHADER_STAGE_GEOMETRY_BIT, // VkShaderStageFlagBits stage;
1062 *geometryShaderModule, // VkShaderModule module;
1063 "main", // VkShader shader;
1064 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1067 shaderStageParams.push_back(geometryShaderStageParams);
1070 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1072 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1073 DE_NULL, // const void* pNext;
1074 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
1075 (deUint32)m_vertexBindingDescriptions.size(), // deUint32 bindingCount;
1076 &m_vertexBindingDescriptions[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1077 (deUint32)m_vertexAttributeDescriptions.size(), // deUint32 attributeCount;
1078 &m_vertexAttributeDescriptions[0], // const VkVertexInputAttributeDescription* pvertexAttributeDescriptions;
1081 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
1083 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1084 DE_NULL, // const void* pNext;
1085 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
1086 VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // VkPrimitiveTopology topology;
1087 DE_FALSE // VkBool32 primitiveRestartEnable;
1090 const VkViewport viewport =
1092 0.0f, // float originX;
1093 0.0f, // float originY;
1094 (float)renderSize.x(), // float width;
1095 (float)renderSize.y(), // float height;
1096 0.0f, // float minDepth;
1097 1.0f // float maxDepth;
1100 const VkRect2D scissor =
1105 }, // VkOffset2D offset;
1107 renderSize.x(), // deUint32 width;
1108 renderSize.y(), // deUint32 height;
1109 }, // VkExtent2D extent;
1112 const VkPipelineViewportStateCreateInfo viewportStateParams =
1114 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
1115 DE_NULL, // const void* pNext;
1116 0u, // VkPipelineViewportStateCreateFlags flags;
1117 1u, // deUint32 viewportCount;
1118 &viewport, // const VkViewport* pViewports;
1119 1u, // deUint32 scissorsCount;
1120 &scissor // const VkRect2D* pScissors;
1123 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
1125 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1126 DE_NULL, // const void* pNext;
1127 (VkPipelineRasterizationStateCreateFlags)0u, //VkPipelineRasterizationStateCreateFlags flags;
1128 VK_FALSE, // VkBool32 depthClipEnable;
1129 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
1130 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
1131 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
1132 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
1133 VK_FALSE, // VkBool32 depthBiasEnable;
1134 0.0f, // float depthBias;
1135 0.0f, // float depthBiasClamp;
1136 0.0f, // float slopeScaledDepthBias;
1137 1.0f // float lineWidth;
1140 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1142 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1143 DE_NULL, // const void* pNext;
1144 0u, // VkPipelineMultisampleStateCreateFlags flags;
1145 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
1146 VK_FALSE, // VkBool32 sampleShadingEnable;
1147 0.0f, // float minSampleShading;
1148 DE_NULL, // const VkSampleMask* pSampleMask;
1149 VK_FALSE, // VkBool32 alphaToCoverageEnable;
1150 VK_FALSE // VkBool32 alphaToOneEnable;
1153 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1155 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1156 DE_NULL, // const void* pNext;
1157 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
1158 VK_FALSE, // VkBool32 logicOpEnable;
1159 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1160 (deUint32)colorBlendAttachmentStates.size(), // deUint32 attachmentCount;
1161 &colorBlendAttachmentStates[0], // const VkPipelineColorBlendAttachmentState* pAttachments;
1162 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConst[4];
1165 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1167 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1168 DE_NULL, // const void* pNext;
1169 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
1170 (deUint32)shaderStageParams.size(), // deUint32 stageCount;
1171 &shaderStageParams[0], // const VkPipelineShaderStageCreateInfo* pStages;
1172 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1173 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1174 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1175 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
1176 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
1177 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1178 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1179 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1180 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
1181 *pipelineLayout, // VkPipelineLayout layout;
1182 *renderPass, // VkRenderPass renderPass;
1183 0u, // deUint32 subpass;
1184 0u, // VkPipeline basePipelineHandle;
1185 0u // deInt32 basePipelineIndex;
1188 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1191 // Create command pool
1192 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1194 // Create command buffer
1196 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1198 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1199 DE_NULL, // const void* pNext;
1200 0u, // VkCmdBufferOptimizeFlags flags;
1201 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1204 const VkRenderPassBeginInfo renderPassBeginInfo =
1206 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1207 DE_NULL, // const void* pNext;
1208 *renderPass, // VkRenderPass renderPass;
1209 *framebuffer, // VkFramebuffer framebuffer;
1210 { { 0, 0 }, { renderSize.x(), renderSize.y() } }, // VkRect2D renderArea;
1211 (deUint32)attachmentClearValues.size(), // deUint32 attachmentCount;
1212 &attachmentClearValues[0] // const VkClearValue* pAttachmentClearValues;
1215 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1217 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1219 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0,
1220 0, (const VkMemoryBarrier*)DE_NULL,
1221 0, (const VkBufferMemoryBarrier*)DE_NULL,
1222 (deUint32)colorImagePreRenderBarriers.size(), colorImagePreRenderBarriers.empty() ? DE_NULL : &colorImagePreRenderBarriers[0]);
1223 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1225 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
1227 if (m_extraResourcesLayout != 0)
1229 DE_ASSERT(extraResources != 0);
1230 const VkDescriptorSet descriptorSets[] = { *emptyDescriptorSet, extraResources };
1231 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, DE_LENGTH_OF_ARRAY(descriptorSets), descriptorSets, 0u, DE_NULL);
1234 DE_ASSERT(extraResources == 0);
1236 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
1238 std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
1240 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
1241 for (size_t i = 0; i < numberOfVertexAttributes; i++)
1243 buffers[i] = m_vertexBuffers[i].get()->get();
1246 vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
1247 vk.cmdDraw(*cmdBuffer, (deUint32)positions.size(), 1u, 0u, 0u);
1249 vk.cmdEndRenderPass(*cmdBuffer);
1250 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
1251 0, (const VkMemoryBarrier*)DE_NULL,
1252 0, (const VkBufferMemoryBarrier*)DE_NULL,
1253 (deUint32)colorImagePostRenderBarriers.size(), colorImagePostRenderBarriers.empty() ? DE_NULL : &colorImagePostRenderBarriers[0]);
1255 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1259 fence = createFence(vk, vkDevice);
1264 const VkSubmitInfo submitInfo =
1266 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
1268 0u, // waitSemaphoreCount
1269 DE_NULL, // pWaitSemaphores
1270 (const VkPipelineStageFlags*)DE_NULL,
1271 1u, // commandBufferCount
1272 &cmdBuffer.get(), // pCommandBuffers
1273 0u, // signalSemaphoreCount
1274 DE_NULL // pSignalSemaphores
1277 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1278 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1279 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), DE_TRUE, ~(0ull) /* infinity*/));
1282 // Read back result and output
1284 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(4 * sizeof(deUint32) * renderSize.x() * renderSize.y());
1285 const VkBufferCreateInfo readImageBufferParams =
1287 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1288 DE_NULL, // const void* pNext;
1289 0u, // VkBufferCreateFlags flags;
1290 imageSizeBytes, // VkDeviceSize size;
1291 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
1292 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1293 1u, // deUint32 queueFamilyCount;
1294 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1297 // constants for image copy
1298 Move<VkCommandPool> copyCmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1300 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1302 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1303 DE_NULL, // const void* pNext;
1304 0u, // VkCmdBufferOptimizeFlags flags;
1305 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1308 const VkBufferImageCopy copyParams =
1310 0u, // VkDeviceSize bufferOffset;
1311 (deUint32)renderSize.x(), // deUint32 bufferRowLength;
1312 (deUint32)renderSize.y(), // deUint32 bufferImageHeight;
1314 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
1315 0u, // deUint32 mipLevel;
1316 0u, // deUint32 arraySlice;
1317 1u, // deUint32 arraySize;
1318 }, // VkImageSubresource imageSubresource;
1319 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
1320 { renderSize.x(), renderSize.y(), 1u } // VkExtent3D imageExtent;
1323 // Read back pixels.
1324 for (int outNdx = 0; outNdx < (int)m_shaderSpec.outputs.size(); ++outNdx)
1326 const Symbol& output = m_shaderSpec.outputs[outNdx];
1327 const int outSize = output.varType.getScalarSize();
1328 const int outVecSize = glu::getDataTypeNumComponents(output.varType.getBasicType());
1329 const int outNumLocs = glu::getDataTypeNumLocations(output.varType.getBasicType());
1330 deUint32* dstPtrBase = static_cast<deUint32*>(outputs[outNdx]);
1331 const int outLocation = de::lookup(m_outputLayout.locationMap, output.name);
1333 for (int locNdx = 0; locNdx < outNumLocs; ++locNdx)
1335 tcu::TextureLevel tmpBuf;
1336 const tcu::TextureFormat format = getRenderbufferFormatForOutput(output.varType, false);
1337 const tcu::TextureFormat readFormat (tcu::TextureFormat::RGBA, format.type);
1338 const Unique<VkBuffer> readImageBuffer(createBuffer(vk, vkDevice, &readImageBufferParams));
1339 const de::UniquePtr<Allocation> readImageBufferMemory(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
1341 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
1343 // Copy image to buffer
1346 Move<VkCommandBuffer> copyCmdBuffer = allocateCommandBuffer(vk, vkDevice, *copyCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1348 const VkSubmitInfo submitInfo =
1350 VK_STRUCTURE_TYPE_SUBMIT_INFO,
1353 (const VkSemaphore*)DE_NULL,
1354 (const VkPipelineStageFlags*)DE_NULL,
1356 ©CmdBuffer.get(),
1358 (const VkSemaphore*)DE_NULL,
1361 VK_CHECK(vk.beginCommandBuffer(*copyCmdBuffer, &cmdBufferBeginInfo));
1362 vk.cmdCopyImageToBuffer(*copyCmdBuffer, colorImages[outLocation + locNdx].get()->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params);
1363 VK_CHECK(vk.endCommandBuffer(*copyCmdBuffer));
1365 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1366 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1367 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
1370 const VkMappedMemoryRange range =
1372 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
1373 DE_NULL, // const void* pNext;
1374 readImageBufferMemory->getMemory(), // VkDeviceMemory mem;
1375 0, // VkDeviceSize offset;
1376 imageSizeBytes, // VkDeviceSize size;
1379 VK_CHECK(vk.invalidateMappedMemoryRanges(vkDevice, 1u, &range));
1381 tmpBuf.setStorage(readFormat, renderSize.x(), renderSize.y());
1383 const tcu::TextureFormat resultFormat(tcu::TextureFormat::RGBA, format.type);
1384 const tcu::ConstPixelBufferAccess resultAccess(resultFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr());
1386 tcu::copy(tmpBuf.getAccess(), resultAccess);
1388 if (outSize == 4 && outNumLocs == 1)
1389 deMemcpy(dstPtrBase, tmpBuf.getAccess().getDataPtr(), numValues * outVecSize * sizeof(deUint32));
1392 for (int valNdx = 0; valNdx < numValues; valNdx++)
1394 const deUint32* srcPtr = (const deUint32*)tmpBuf.getAccess().getDataPtr() + valNdx * 4;
1395 deUint32* dstPtr = &dstPtrBase[outSize * valNdx + outVecSize * locNdx];
1396 deMemcpy(dstPtr, srcPtr, outVecSize * sizeof(deUint32));
1404 // VertexShaderExecutor
1406 class VertexShaderExecutor : public FragmentOutExecutor
1409 VertexShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1410 virtual ~VertexShaderExecutor (void);
1412 static void generateSources (const ShaderSpec& shaderSpec, SourceCollections& dst);
1415 VertexShaderExecutor::VertexShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1416 : FragmentOutExecutor(context, glu::SHADERTYPE_VERTEX, shaderSpec, extraResourcesLayout)
1420 VertexShaderExecutor::~VertexShaderExecutor (void)
1424 void VertexShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1426 const FragmentOutputLayout outputLayout (computeFragmentOutputLayout(shaderSpec.outputs));
1428 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShader(shaderSpec, "a_", "vtx_out_")) << shaderSpec.buildOptions;
1429 /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1430 programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(shaderSpec, false, outputLayout.locationMap, "vtx_out_", "o_")) << shaderSpec.buildOptions;
1433 // GeometryShaderExecutor
1435 class GeometryShaderExecutor : public FragmentOutExecutor
1438 GeometryShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1439 virtual ~GeometryShaderExecutor (void);
1441 static void generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
1445 GeometryShaderExecutor::GeometryShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1446 : FragmentOutExecutor(context, glu::SHADERTYPE_GEOMETRY, shaderSpec, extraResourcesLayout)
1448 const VkPhysicalDeviceFeatures& features = context.getDeviceFeatures();
1450 if (!features.geometryShader)
1451 TCU_THROW(NotSupportedError, "Geometry shader type not supported by device");
1454 GeometryShaderExecutor::~GeometryShaderExecutor (void)
1458 void GeometryShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1460 const FragmentOutputLayout outputLayout (computeFragmentOutputLayout(shaderSpec.outputs));
1462 programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(shaderSpec.inputs, "a_", "vtx_out_")) << shaderSpec.buildOptions;
1464 programCollection.glslSources.add("geom") << glu::GeometrySource(generateGeometryShader(shaderSpec, "vtx_out_", "geom_out_")) << shaderSpec.buildOptions;
1466 /* \todo [2015-09-18 rsipka] set useIntOutputs parameter if needed. */
1467 programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(shaderSpec, false, outputLayout.locationMap, "geom_out_", "o_")) << shaderSpec.buildOptions;
1471 // FragmentShaderExecutor
1473 class FragmentShaderExecutor : public FragmentOutExecutor
1476 FragmentShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1477 virtual ~FragmentShaderExecutor (void);
1479 static void generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
1483 FragmentShaderExecutor::FragmentShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1484 : FragmentOutExecutor(context, glu::SHADERTYPE_FRAGMENT, shaderSpec, extraResourcesLayout)
1488 FragmentShaderExecutor::~FragmentShaderExecutor (void)
1492 void FragmentShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1494 const FragmentOutputLayout outputLayout (computeFragmentOutputLayout(shaderSpec.outputs));
1496 programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(shaderSpec.inputs, "a_", "vtx_out_")) << shaderSpec.buildOptions;
1497 /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1498 programCollection.glslSources.add("frag") << glu::FragmentSource(generateFragmentShader(shaderSpec, false, outputLayout.locationMap, "vtx_out_", "o_")) << shaderSpec.buildOptions;
1501 // Shared utilities for compute and tess executors
1503 static deUint32 getVecStd430ByteAlignment (glu::DataType type)
1505 switch (glu::getDataTypeScalarSize(type))
1517 class BufferIoExecutor : public ShaderExecutor
1520 BufferIoExecutor (Context& context, const ShaderSpec& shaderSpec);
1521 virtual ~BufferIoExecutor (void);
1526 INPUT_BUFFER_BINDING = 0,
1527 OUTPUT_BUFFER_BINDING = 1,
1530 void initBuffers (int numValues);
1531 VkBuffer getInputBuffer (void) const { return *m_inputBuffer; }
1532 VkBuffer getOutputBuffer (void) const { return *m_outputBuffer; }
1533 deUint32 getInputStride (void) const { return getLayoutStride(m_inputLayout); }
1534 deUint32 getOutputStride (void) const { return getLayoutStride(m_outputLayout); }
1536 void uploadInputBuffer (const void* const* inputPtrs, int numValues);
1537 void readOutputBuffer (void* const* outputPtrs, int numValues);
1539 static void declareBufferBlocks (std::ostream& src, const ShaderSpec& spec);
1540 static void generateExecBufferIo(std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName);
1543 Move<VkBuffer> m_inputBuffer;
1544 Move<VkBuffer> m_outputBuffer;
1551 deUint32 matrixStride;
1553 VarLayout (void) : offset(0), stride(0), matrixStride(0) {}
1556 static void computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout);
1557 static deUint32 getLayoutStride (const vector<VarLayout>& layout);
1559 static void copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1560 static void copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1562 de::MovePtr<Allocation> m_inputAlloc;
1563 de::MovePtr<Allocation> m_outputAlloc;
1565 vector<VarLayout> m_inputLayout;
1566 vector<VarLayout> m_outputLayout;
1569 BufferIoExecutor::BufferIoExecutor (Context& context, const ShaderSpec& shaderSpec)
1570 : ShaderExecutor(context, shaderSpec)
1572 computeVarLayout(m_shaderSpec.inputs, &m_inputLayout);
1573 computeVarLayout(m_shaderSpec.outputs, &m_outputLayout);
1576 BufferIoExecutor::~BufferIoExecutor (void)
1580 inline deUint32 BufferIoExecutor::getLayoutStride (const vector<VarLayout>& layout)
1582 return layout.empty() ? 0 : layout[0].stride;
1585 void BufferIoExecutor::computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout)
1587 deUint32 maxAlignment = 0;
1588 deUint32 curOffset = 0;
1590 DE_ASSERT(layout != DE_NULL);
1591 DE_ASSERT(layout->empty());
1592 layout->resize(symbols.size());
1594 for (size_t varNdx = 0; varNdx < symbols.size(); varNdx++)
1596 const Symbol& symbol = symbols[varNdx];
1597 const glu::DataType basicType = symbol.varType.getBasicType();
1598 VarLayout& layoutEntry = (*layout)[varNdx];
1600 if (glu::isDataTypeScalarOrVector(basicType))
1602 const deUint32 alignment = getVecStd430ByteAlignment(basicType);
1603 const deUint32 size = (deUint32)glu::getDataTypeScalarSize(basicType) * (int)sizeof(deUint32);
1605 curOffset = (deUint32)deAlign32((int)curOffset, (int)alignment);
1606 maxAlignment = de::max(maxAlignment, alignment);
1608 layoutEntry.offset = curOffset;
1609 layoutEntry.matrixStride = 0;
1613 else if (glu::isDataTypeMatrix(basicType))
1615 const int numVecs = glu::getDataTypeMatrixNumColumns(basicType);
1616 const glu::DataType vecType = glu::getDataTypeFloatVec(glu::getDataTypeMatrixNumRows(basicType));
1617 const deUint32 vecAlignment = getVecStd430ByteAlignment(vecType);
1619 curOffset = (deUint32)deAlign32((int)curOffset, (int)vecAlignment);
1620 maxAlignment = de::max(maxAlignment, vecAlignment);
1622 layoutEntry.offset = curOffset;
1623 layoutEntry.matrixStride = vecAlignment;
1625 curOffset += vecAlignment*numVecs;
1632 const deUint32 totalSize = (deUint32)deAlign32(curOffset, maxAlignment);
1634 for (vector<VarLayout>::iterator varIter = layout->begin(); varIter != layout->end(); ++varIter)
1635 varIter->stride = totalSize;
1639 void BufferIoExecutor::declareBufferBlocks (std::ostream& src, const ShaderSpec& spec)
1642 if (!spec.inputs.empty())
1644 glu::StructType inputStruct("Inputs");
1645 for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1646 inputStruct.addMember(symIter->name.c_str(), symIter->varType);
1647 src << glu::declare(&inputStruct) << ";\n";
1652 glu::StructType outputStruct("Outputs");
1653 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1654 outputStruct.addMember(symIter->name.c_str(), symIter->varType);
1655 src << glu::declare(&outputStruct) << ";\n";
1660 if (!spec.inputs.empty())
1662 src << "layout(set = 0, binding = " << int(INPUT_BUFFER_BINDING) << ", std430) buffer InBuffer\n"
1664 << " Inputs inputs[];\n"
1668 src << "layout(set = 0, binding = " << int(OUTPUT_BUFFER_BINDING) << ", std430) buffer OutBuffer\n"
1670 << " Outputs outputs[];\n"
1675 void BufferIoExecutor::generateExecBufferIo (std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName)
1677 for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1678 src << "\t" << glu::declare(symIter->varType, symIter->name) << " = inputs[" << invocationNdxName << "]." << symIter->name << ";\n";
1680 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1681 src << "\t" << glu::declare(symIter->varType, symIter->name) << ";\n";
1686 std::istringstream opSrc (spec.source);
1689 while (std::getline(opSrc, line))
1690 src << "\t" << line << "\n";
1694 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1695 src << "\toutputs[" << invocationNdxName << "]." << symIter->name << " = " << symIter->name << ";\n";
1698 void BufferIoExecutor::copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1700 if (varType.isBasicType())
1702 const glu::DataType basicType = varType.getBasicType();
1703 const bool isMatrix = glu::isDataTypeMatrix(basicType);
1704 const int scalarSize = glu::getDataTypeScalarSize(basicType);
1705 const int numVecs = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1706 const int numComps = scalarSize / numVecs;
1708 for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1710 for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1712 const int srcOffset = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1713 const int dstOffset = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1714 const deUint8* srcPtr = (const deUint8*)srcBasePtr + srcOffset;
1715 deUint8* dstPtr = (deUint8*)dstBasePtr + dstOffset;
1717 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1722 throw tcu::InternalError("Unsupported type");
1725 void BufferIoExecutor::copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1727 if (varType.isBasicType())
1729 const glu::DataType basicType = varType.getBasicType();
1730 const bool isMatrix = glu::isDataTypeMatrix(basicType);
1731 const int scalarSize = glu::getDataTypeScalarSize(basicType);
1732 const int numVecs = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1733 const int numComps = scalarSize / numVecs;
1735 for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1737 for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1739 const int srcOffset = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1740 const int dstOffset = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1741 const deUint8* srcPtr = (const deUint8*)srcBasePtr + srcOffset;
1742 deUint8* dstPtr = (deUint8*)dstBasePtr + dstOffset;
1744 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1749 throw tcu::InternalError("Unsupported type");
1752 void BufferIoExecutor::uploadInputBuffer (const void* const* inputPtrs, int numValues)
1754 const VkDevice vkDevice = m_context.getDevice();
1755 const DeviceInterface& vk = m_context.getDeviceInterface();
1757 const deUint32 inputStride = getLayoutStride(m_inputLayout);
1758 const int inputBufferSize = inputStride * numValues;
1760 if (inputBufferSize == 0)
1761 return; // No inputs
1763 DE_ASSERT(m_shaderSpec.inputs.size() == m_inputLayout.size());
1764 for (size_t inputNdx = 0; inputNdx < m_shaderSpec.inputs.size(); ++inputNdx)
1766 const glu::VarType& varType = m_shaderSpec.inputs[inputNdx].varType;
1767 const VarLayout& layout = m_inputLayout[inputNdx];
1769 copyToBuffer(varType, layout, numValues, inputPtrs[inputNdx], m_inputAlloc->getHostPtr());
1772 flushMappedMemoryRange(vk, vkDevice, m_inputAlloc->getMemory(), m_inputAlloc->getOffset(), inputBufferSize);
1775 void BufferIoExecutor::readOutputBuffer (void* const* outputPtrs, int numValues)
1777 const VkDevice vkDevice = m_context.getDevice();
1778 const DeviceInterface& vk = m_context.getDeviceInterface();
1780 const deUint32 outputStride = getLayoutStride(m_outputLayout);
1781 const int outputBufferSize = numValues * outputStride;
1783 DE_ASSERT(outputBufferSize > 0); // At least some outputs are required.
1785 invalidateMappedMemoryRange(vk, vkDevice, m_outputAlloc->getMemory(), m_outputAlloc->getOffset(), outputBufferSize);
1787 DE_ASSERT(m_shaderSpec.outputs.size() == m_outputLayout.size());
1788 for (size_t outputNdx = 0; outputNdx < m_shaderSpec.outputs.size(); ++outputNdx)
1790 const glu::VarType& varType = m_shaderSpec.outputs[outputNdx].varType;
1791 const VarLayout& layout = m_outputLayout[outputNdx];
1793 copyFromBuffer(varType, layout, numValues, m_outputAlloc->getHostPtr(), outputPtrs[outputNdx]);
1797 void BufferIoExecutor::initBuffers (int numValues)
1799 const deUint32 inputStride = getLayoutStride(m_inputLayout);
1800 const deUint32 outputStride = getLayoutStride(m_outputLayout);
1801 // Avoid creating zero-sized buffer/memory
1802 const size_t inputBufferSize = numValues * inputStride ? (numValues * inputStride) : 1;
1803 const size_t outputBufferSize = numValues * outputStride;
1805 // Upload data to buffer
1806 const VkDevice vkDevice = m_context.getDevice();
1807 const DeviceInterface& vk = m_context.getDeviceInterface();
1808 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1809 Allocator& memAlloc = m_context.getDefaultAllocator();
1811 const VkBufferCreateInfo inputBufferParams =
1813 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1814 DE_NULL, // const void* pNext;
1815 0u, // VkBufferCreateFlags flags;
1816 inputBufferSize, // VkDeviceSize size;
1817 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
1818 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1819 1u, // deUint32 queueFamilyCount;
1820 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1823 m_inputBuffer = createBuffer(vk, vkDevice, &inputBufferParams);
1824 m_inputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_inputBuffer), MemoryRequirement::HostVisible);
1826 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_inputBuffer, m_inputAlloc->getMemory(), m_inputAlloc->getOffset()));
1828 const VkBufferCreateInfo outputBufferParams =
1830 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1831 DE_NULL, // const void* pNext;
1832 0u, // VkBufferCreateFlags flags;
1833 outputBufferSize, // VkDeviceSize size;
1834 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
1835 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1836 1u, // deUint32 queueFamilyCount;
1837 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1840 m_outputBuffer = createBuffer(vk, vkDevice, &outputBufferParams);
1841 m_outputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_outputBuffer), MemoryRequirement::HostVisible);
1843 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_outputBuffer, m_outputAlloc->getMemory(), m_outputAlloc->getOffset()));
1846 // ComputeShaderExecutor
1848 class ComputeShaderExecutor : public BufferIoExecutor
1851 ComputeShaderExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
1852 virtual ~ComputeShaderExecutor (void);
1854 static void generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
1856 virtual void execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources);
1859 static std::string generateComputeShader (const ShaderSpec& spec);
1862 const VkDescriptorSetLayout m_extraResourcesLayout;
1865 ComputeShaderExecutor::ComputeShaderExecutor(Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
1866 : BufferIoExecutor (context, shaderSpec)
1867 , m_extraResourcesLayout (extraResourcesLayout)
1871 ComputeShaderExecutor::~ComputeShaderExecutor (void)
1875 std::string ComputeShaderExecutor::generateComputeShader (const ShaderSpec& spec)
1877 std::ostringstream src;
1878 src << glu::getGLSLVersionDeclaration(spec.glslVersion) << "\n";
1880 if (!spec.globalDeclarations.empty())
1881 src << spec.globalDeclarations << "\n";
1883 src << "layout(local_size_x = 1) in;\n"
1886 declareBufferBlocks(src, spec);
1888 src << "void main (void)\n"
1890 << " uint invocationNdx = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z\n"
1891 << " + gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n";
1893 generateExecBufferIo(src, spec, "invocationNdx");
1900 void ComputeShaderExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
1902 programCollection.glslSources.add("compute") << glu::ComputeSource(generateComputeShader(shaderSpec)) << shaderSpec.buildOptions;
1905 void ComputeShaderExecutor::execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources)
1907 const VkDevice vkDevice = m_context.getDevice();
1908 const DeviceInterface& vk = m_context.getDeviceInterface();
1909 const VkQueue queue = m_context.getUniversalQueue();
1910 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1912 DescriptorPoolBuilder descriptorPoolBuilder;
1913 DescriptorSetLayoutBuilder descriptorSetLayoutBuilder;
1915 Move<VkShaderModule> computeShaderModule;
1916 Move<VkPipeline> computePipeline;
1917 Move<VkPipelineLayout> pipelineLayout;
1918 Move<VkCommandPool> cmdPool;
1919 Move<VkDescriptorPool> descriptorPool;
1920 Move<VkDescriptorSetLayout> descriptorSetLayout;
1921 Move<VkDescriptorSet> descriptorSet;
1922 const deUint32 numDescriptorSets = (m_extraResourcesLayout != 0) ? 2u : 1u;
1923 Move<VkFence> fence;
1925 DE_ASSERT((m_extraResourcesLayout != 0) == (extraResources != 0));
1927 initBuffers(numValues);
1929 // Setup input buffer & copy data
1930 uploadInputBuffer(inputs, numValues);
1932 // Create command pool
1933 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1935 // Create command buffer
1936 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1938 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1939 DE_NULL, // const void* pNext;
1940 0u, // VkCmdBufferOptimizeFlags flags;
1941 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1944 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1945 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1946 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1947 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1949 descriptorSetLayout = descriptorSetLayoutBuilder.build(vk, vkDevice);
1950 descriptorPool = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1952 const VkDescriptorSetAllocateInfo allocInfo =
1954 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1958 &*descriptorSetLayout
1961 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
1963 // Create pipeline layout
1965 const VkDescriptorSetLayout descriptorSetLayouts[] =
1967 *descriptorSetLayout,
1968 m_extraResourcesLayout
1970 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1972 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1973 DE_NULL, // const void* pNext;
1974 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
1975 numDescriptorSets, // deUint32 CdescriptorSetCount;
1976 descriptorSetLayouts, // const VkDescriptorSetLayout* pSetLayouts;
1977 0u, // deUint32 pushConstantRangeCount;
1978 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1981 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1986 computeShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("compute"), 0);
1991 const VkPipelineShaderStageCreateInfo shaderStageParams[1] =
1994 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1995 DE_NULL, // const void* pNext;
1996 (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
1997 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagsBit stage;
1998 *computeShaderModule, // VkShaderModule shader;
1999 "main", // const char* pName;
2000 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2004 const VkComputePipelineCreateInfo computePipelineParams =
2006 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
2007 DE_NULL, // const void* pNext;
2008 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
2009 *shaderStageParams, // VkPipelineShaderStageCreateInfo cs;
2010 *pipelineLayout, // VkPipelineLayout layout;
2011 0u, // VkPipeline basePipelineHandle;
2012 0u, // int32_t basePipelineIndex;
2015 computePipeline = createComputePipeline(vk, vkDevice, DE_NULL, &computePipelineParams);
2019 fence = createFence(vk, vkDevice);
2021 const int maxValuesPerInvocation = m_context.getDeviceProperties().limits.maxComputeWorkGroupSize[0];
2023 const deUint32 inputStride = getInputStride();
2024 const deUint32 outputStride = getOutputStride();
2026 while (curOffset < numValues)
2028 Move<VkCommandBuffer> cmdBuffer;
2029 const int numToExec = de::min(maxValuesPerInvocation, numValues-curOffset);
2031 // Update descriptors
2033 DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2035 const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2037 *m_outputBuffer, // VkBuffer buffer;
2038 curOffset * outputStride, // VkDeviceSize offset;
2039 numToExec * outputStride // VkDeviceSize range;
2042 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2046 const VkDescriptorBufferInfo inputDescriptorBufferInfo =
2048 *m_inputBuffer, // VkBuffer buffer;
2049 curOffset * inputStride, // VkDeviceSize offset;
2050 numToExec * inputStride // VkDeviceSize range;
2053 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2056 descriptorSetUpdateBuilder.update(vk, vkDevice);
2059 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2060 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2061 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
2064 const VkDescriptorSet descriptorSets[] = { *descriptorSet, extraResources };
2065 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, numDescriptorSets, descriptorSets, 0u, DE_NULL);
2068 vk.cmdDispatch(*cmdBuffer, numToExec, 1, 1);
2070 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2072 curOffset += numToExec;
2076 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2078 const VkSubmitInfo submitInfo =
2080 VK_STRUCTURE_TYPE_SUBMIT_INFO,
2083 (const VkSemaphore*)DE_NULL,
2084 (const VkPipelineStageFlags*)DE_NULL,
2088 (const VkSemaphore*)DE_NULL,
2091 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2092 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2097 readOutputBuffer(outputs, numValues);
2100 // Tessellation utils
2102 static std::string generateVertexShaderForTess (void)
2104 std::ostringstream src;
2105 src << "#version 310 es\n"
2106 << "void main (void)\n{\n"
2107 << " gl_Position = vec4(gl_VertexIndex/2, gl_VertexIndex%2, 0.0, 1.0);\n"
2113 class TessellationExecutor : public BufferIoExecutor
2116 TessellationExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
2117 virtual ~TessellationExecutor (void);
2119 void renderTess (deUint32 numValues, deUint32 vertexCount, deUint32 patchControlPoints, VkDescriptorSet extraResources);
2122 const VkDescriptorSetLayout m_extraResourcesLayout;
2125 TessellationExecutor::TessellationExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2126 : BufferIoExecutor (context, shaderSpec)
2127 , m_extraResourcesLayout (extraResourcesLayout)
2129 const VkPhysicalDeviceFeatures& features = context.getDeviceFeatures();
2131 if (!features.tessellationShader)
2132 TCU_THROW(NotSupportedError, "Tessellation shader is not supported by device");
2135 TessellationExecutor::~TessellationExecutor (void)
2139 void TessellationExecutor::renderTess (deUint32 numValues, deUint32 vertexCount, deUint32 patchControlPoints, VkDescriptorSet extraResources)
2141 const size_t inputBufferSize = numValues * getInputStride();
2142 const VkDevice vkDevice = m_context.getDevice();
2143 const DeviceInterface& vk = m_context.getDeviceInterface();
2144 const VkQueue queue = m_context.getUniversalQueue();
2145 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2146 Allocator& memAlloc = m_context.getDefaultAllocator();
2148 const tcu::UVec2 renderSize (DEFAULT_RENDER_WIDTH, DEFAULT_RENDER_HEIGHT);
2150 Move<VkImage> colorImage;
2151 de::MovePtr<Allocation> colorImageAlloc;
2152 VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
2153 Move<VkImageView> colorImageView;
2155 Move<VkRenderPass> renderPass;
2156 Move<VkFramebuffer> framebuffer;
2157 Move<VkPipelineLayout> pipelineLayout;
2158 Move<VkPipeline> graphicsPipeline;
2160 Move<VkShaderModule> vertexShaderModule;
2161 Move<VkShaderModule> tessControlShaderModule;
2162 Move<VkShaderModule> tessEvalShaderModule;
2163 Move<VkShaderModule> fragmentShaderModule;
2165 Move<VkCommandPool> cmdPool;
2166 Move<VkCommandBuffer> cmdBuffer;
2168 Move<VkFence> fence;
2170 Move<VkDescriptorPool> descriptorPool;
2171 Move<VkDescriptorSetLayout> descriptorSetLayout;
2172 Move<VkDescriptorSet> descriptorSet;
2173 const deUint32 numDescriptorSets = (m_extraResourcesLayout != 0) ? 2u : 1u;
2175 DE_ASSERT((m_extraResourcesLayout != 0) == (extraResources != 0));
2177 // Create color image
2179 const VkImageCreateInfo colorImageParams =
2181 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2182 DE_NULL, // const void* pNext;
2183 0u, // VkImageCreateFlags flags;
2184 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2185 colorFormat, // VkFormat format;
2186 { renderSize.x(), renderSize.y(), 1u }, // VkExtent3D extent;
2187 1u, // deUint32 mipLevels;
2188 1u, // deUint32 arraySize;
2189 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2190 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2191 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
2192 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2193 1u, // deUint32 queueFamilyCount;
2194 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2195 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
2198 colorImage = createImage(vk, vkDevice, &colorImageParams);
2200 // Allocate and bind color image memory
2201 colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *colorImage), MemoryRequirement::Any);
2202 VK_CHECK(vk.bindImageMemory(vkDevice, *colorImage, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
2205 // Create color attachment view
2207 const VkImageViewCreateInfo colorImageViewParams =
2209 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2210 DE_NULL, // const void* pNext;
2211 0u, // VkImageViewCreateFlags flags;
2212 *colorImage, // VkImage image;
2213 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2214 colorFormat, // VkFormat format;
2216 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
2217 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
2218 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
2219 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
2220 }, // VkComponentsMapping components;
2222 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2223 0u, // deUint32 baseMipLevel;
2224 1u, // deUint32 mipLevels;
2225 0u, // deUint32 baseArraylayer;
2226 1u // deUint32 layerCount;
2227 } // VkImageSubresourceRange subresourceRange;
2230 colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
2233 // Create render pass
2235 const VkAttachmentDescription colorAttachmentDescription =
2237 0u, // VkAttachmentDescriptorFlags flags;
2238 colorFormat, // VkFormat format;
2239 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2240 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
2241 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2242 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2243 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
2244 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2245 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
2248 const VkAttachmentDescription attachments[1] =
2250 colorAttachmentDescription
2253 const VkAttachmentReference colorAttachmentReference =
2255 0u, // deUint32 attachment;
2256 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
2259 const VkSubpassDescription subpassDescription =
2261 0u, // VkSubpassDescriptionFlags flags;
2262 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
2263 0u, // deUint32 inputCount;
2264 DE_NULL, // const VkAttachmentReference* pInputAttachments;
2265 1u, // deUint32 colorCount;
2266 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
2267 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
2268 DE_NULL, // VkAttachmentReference depthStencilAttachment;
2269 0u, // deUint32 preserveCount;
2270 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
2273 const VkRenderPassCreateInfo renderPassParams =
2275 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
2276 DE_NULL, // const void* pNext;
2277 0u, // VkRenderPassCreateFlags flags;
2278 1u, // deUint32 attachmentCount;
2279 attachments, // const VkAttachmentDescription* pAttachments;
2280 1u, // deUint32 subpassCount;
2281 &subpassDescription, // const VkSubpassDescription* pSubpasses;
2282 0u, // deUint32 dependencyCount;
2283 DE_NULL // const VkSubpassDependency* pDependencies;
2286 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
2289 // Create framebuffer
2291 const VkFramebufferCreateInfo framebufferParams =
2293 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
2294 DE_NULL, // const void* pNext;
2295 0u, // VkFramebufferCreateFlags flags;
2296 *renderPass, // VkRenderPass renderPass;
2297 1u, // deUint32 attachmentCount;
2298 &*colorImageView, // const VkAttachmentBindInfo* pAttachments;
2299 (deUint32)renderSize.x(), // deUint32 width;
2300 (deUint32)renderSize.y(), // deUint32 height;
2301 1u // deUint32 layers;
2304 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
2307 // Create descriptors
2309 DescriptorPoolBuilder descriptorPoolBuilder;
2310 DescriptorSetLayoutBuilder descriptorSetLayoutBuilder;
2312 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2313 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2314 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2315 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2317 descriptorSetLayout = descriptorSetLayoutBuilder.build(vk, vkDevice);
2318 descriptorPool = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2320 const VkDescriptorSetAllocateInfo allocInfo =
2322 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2326 &*descriptorSetLayout
2329 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2330 // Update descriptors
2332 DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2333 const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2335 *m_outputBuffer, // VkBuffer buffer;
2336 0u, // VkDeviceSize offset;
2337 VK_WHOLE_SIZE // VkDeviceSize range;
2340 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2342 VkDescriptorBufferInfo inputDescriptorBufferInfo =
2344 0, // VkBuffer buffer;
2345 0u, // VkDeviceSize offset;
2346 VK_WHOLE_SIZE // VkDeviceSize range;
2349 if (inputBufferSize > 0)
2351 inputDescriptorBufferInfo.buffer = *m_inputBuffer;
2353 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2356 descriptorSetUpdateBuilder.update(vk, vkDevice);
2360 // Create pipeline layout
2362 const VkDescriptorSetLayout descriptorSetLayouts[] =
2364 *descriptorSetLayout,
2365 m_extraResourcesLayout
2367 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2369 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
2370 DE_NULL, // const void* pNext;
2371 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
2372 numDescriptorSets, // deUint32 descriptorSetCount;
2373 descriptorSetLayouts, // const VkDescriptorSetLayout* pSetLayouts;
2374 0u, // deUint32 pushConstantRangeCount;
2375 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
2378 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2381 // Create shader modules
2383 vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
2384 tessControlShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tess_control"), 0);
2385 tessEvalShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tess_eval"), 0);
2386 fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
2391 const VkPipelineShaderStageCreateInfo shaderStageParams[4] =
2394 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2395 DE_NULL, // const void* pNext;
2396 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2397 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBit stage;
2398 *vertexShaderModule, // VkShaderModule shader;
2399 "main", // const char* pName;
2400 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2403 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2404 DE_NULL, // const void* pNext;
2405 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2406 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, // VkShaderStageFlagBit stage;
2407 *tessControlShaderModule, // VkShaderModule shader;
2408 "main", // const char* pName;
2409 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2412 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2413 DE_NULL, // const void* pNext;
2414 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2415 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, // VkShaderStageFlagBit stage;
2416 *tessEvalShaderModule, // VkShaderModule shader;
2417 "main", // const char* pName;
2418 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2421 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2422 DE_NULL, // const void* pNext;
2423 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2424 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBit stage;
2425 *fragmentShaderModule, // VkShaderModule shader;
2426 "main", // const char* pName;
2427 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2431 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
2433 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
2434 DE_NULL, // const void* pNext;
2435 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
2436 0u, // deUint32 bindingCount;
2437 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
2438 0u, // deUint32 attributeCount;
2439 DE_NULL, // const VkVertexInputAttributeDescription* pvertexAttributeDescriptions;
2442 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
2444 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
2445 DE_NULL, // const void* pNext;
2446 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2447 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, // VkPrimitiveTopology topology;
2448 DE_FALSE // VkBool32 primitiveRestartEnable;
2451 struct VkPipelineTessellationStateCreateInfo tessellationStateParams =
2453 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
2454 DE_NULL, // const void* pNext;
2455 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags;
2456 patchControlPoints // uint32_t patchControlPoints;
2459 const VkViewport viewport =
2461 0.0f, // float originX;
2462 0.0f, // float originY;
2463 (float)renderSize.x(), // float width;
2464 (float)renderSize.y(), // float height;
2465 0.0f, // float minDepth;
2466 1.0f // float maxDepth;
2469 const VkRect2D scissor =
2474 }, // VkOffset2D offset;
2476 renderSize.x(), // deUint32 width;
2477 renderSize.y(), // deUint32 height;
2478 }, // VkExtent2D extent;
2481 const VkPipelineViewportStateCreateInfo viewportStateParams =
2483 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
2484 DE_NULL, // const void* pNext;
2485 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewPortStateCreateFlags flags;
2486 1u, // deUint32 viewportCount;
2487 &viewport, // const VkViewport* pViewports;
2488 1u, // deUint32 scissorsCount;
2489 &scissor // const VkRect2D* pScissors;
2492 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
2494 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
2495 DE_NULL, // const void* pNext;
2496 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStageCreateFlags flags;
2497 VK_FALSE, // VkBool32 depthClipEnable;
2498 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
2499 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
2500 VK_CULL_MODE_NONE, // VkCullMode cullMode;
2501 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
2502 VK_FALSE, // VkBool32 depthBiasEnable;
2503 0.0f, // float depthBias;
2504 0.0f, // float depthBiasClamp;
2505 0.0f, // float slopeScaledDepthBias;
2506 1.0f // float lineWidth;
2509 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
2511 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
2512 DE_NULL, // const void* pNext;
2513 0u, // VkPipelineMultisampleStateCreateFlags flags;
2514 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
2515 VK_FALSE, // VkBool32 sampleShadingEnable;
2516 0.0f, // float minSampleShading;
2517 DE_NULL, // const VkSampleMask* pSampleMask;
2518 VK_FALSE, // VkBool32 alphaToCoverageEnable;
2519 VK_FALSE // VkBool32 alphaToOneEnable;
2522 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
2524 VK_FALSE, // VkBool32 blendEnable;
2525 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcBlendColor;
2526 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destBlendColor;
2527 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
2528 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcBlendAlpha;
2529 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destBlendAlpha;
2530 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
2531 (VK_COLOR_COMPONENT_R_BIT |
2532 VK_COLOR_COMPONENT_G_BIT |
2533 VK_COLOR_COMPONENT_B_BIT |
2534 VK_COLOR_COMPONENT_A_BIT) // VkColorComponentFlags colorWriteMask;
2537 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
2539 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
2540 DE_NULL, // const void* pNext;
2541 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags
2542 VK_FALSE, // VkBool32 logicOpEnable;
2543 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
2544 1u, // deUint32 attachmentCount;
2545 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
2546 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConst[4];
2549 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
2551 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
2552 DE_NULL, // const void* pNext;
2553 0u, // VkPipelineCreateFlags flags;
2554 4u, // deUint32 stageCount;
2555 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages;
2556 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
2557 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
2558 &tessellationStateParams, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
2559 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
2560 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
2561 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
2562 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
2563 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
2564 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
2565 *pipelineLayout, // VkPipelineLayout layout;
2566 *renderPass, // VkRenderPass renderPass;
2567 0u, // deUint32 subpass;
2568 0u, // VkPipeline basePipelineHandle;
2569 0u // deInt32 basePipelineIndex;
2572 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
2575 // Create command pool
2576 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
2578 // Create command buffer
2580 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
2582 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
2583 DE_NULL, // const void* pNext;
2584 0u, // VkCmdBufferOptimizeFlags flags;
2585 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2588 const VkClearValue clearValues[1] =
2590 getDefaultClearColor()
2593 const VkRenderPassBeginInfo renderPassBeginInfo =
2595 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
2596 DE_NULL, // const void* pNext;
2597 *renderPass, // VkRenderPass renderPass;
2598 *framebuffer, // VkFramebuffer framebuffer;
2599 { { 0, 0 }, { renderSize.x(), renderSize.y() } }, // VkRect2D renderArea;
2600 1, // deUint32 attachmentCount;
2601 clearValues // const VkClearValue* pClearValues;
2604 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2606 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2608 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2610 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
2613 const VkDescriptorSet descriptorSets[] = { *descriptorSet, extraResources };
2614 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, numDescriptorSets, descriptorSets, 0u, DE_NULL);
2617 vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
2619 vk.cmdEndRenderPass(*cmdBuffer);
2620 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2624 fence = createFence(vk, vkDevice);
2628 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2629 const VkSubmitInfo submitInfo =
2631 VK_STRUCTURE_TYPE_SUBMIT_INFO,
2634 (const VkSemaphore*)0,
2635 (const VkPipelineStageFlags*)DE_NULL,
2639 (const VkSemaphore*)0,
2641 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2642 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2646 // TessControlExecutor
2648 class TessControlExecutor : public TessellationExecutor
2651 TessControlExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
2652 virtual ~TessControlExecutor (void);
2654 static void generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
2656 virtual void execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources);
2659 static std::string generateTessControlShader (const ShaderSpec& shaderSpec);
2662 TessControlExecutor::TessControlExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2663 : TessellationExecutor(context, shaderSpec, extraResourcesLayout)
2667 TessControlExecutor::~TessControlExecutor (void)
2671 std::string TessControlExecutor::generateTessControlShader (const ShaderSpec& shaderSpec)
2673 std::ostringstream src;
2674 src << glu::getGLSLVersionDeclaration(shaderSpec.glslVersion) << "\n";
2676 if (shaderSpec.glslVersion == glu::GLSL_VERSION_310_ES)
2677 src << "#extension GL_EXT_tessellation_shader : require\n\n";
2679 if (!shaderSpec.globalDeclarations.empty())
2680 src << shaderSpec.globalDeclarations << "\n";
2682 src << "\nlayout(vertices = 1) out;\n\n";
2684 declareBufferBlocks(src, shaderSpec);
2686 src << "void main (void)\n{\n";
2688 for (int ndx = 0; ndx < 2; ndx++)
2689 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2691 for (int ndx = 0; ndx < 4; ndx++)
2692 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2695 << "\thighp uint invocationId = uint(gl_PrimitiveID);\n";
2697 generateExecBufferIo(src, shaderSpec, "invocationId");
2704 static std::string generateEmptyTessEvalShader ()
2706 std::ostringstream src;
2708 src << "#version 310 es\n"
2709 "#extension GL_EXT_tessellation_shader : require\n\n";
2711 src << "layout(triangles, ccw) in;\n";
2713 src << "\nvoid main (void)\n{\n"
2714 << "\tgl_Position = vec4(gl_TessCoord.xy, 0.0, 1.0);\n"
2720 void TessControlExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
2722 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess()) << shaderSpec.buildOptions;
2723 programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generateTessControlShader(shaderSpec)) << shaderSpec.buildOptions;
2724 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateEmptyTessEvalShader()) << shaderSpec.buildOptions;
2725 programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource()) << shaderSpec.buildOptions;
2728 void TessControlExecutor::execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources)
2730 const deUint32 patchSize = 3;
2732 initBuffers(numValues);
2734 // Setup input buffer & copy data
2735 uploadInputBuffer(inputs, numValues);
2737 renderTess(numValues, patchSize * numValues, patchSize, extraResources);
2740 readOutputBuffer(outputs, numValues);
2743 // TessEvaluationExecutor
2745 class TessEvaluationExecutor : public TessellationExecutor
2748 TessEvaluationExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout);
2749 virtual ~TessEvaluationExecutor (void);
2751 static void generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection);
2753 virtual void execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources);
2756 static std::string generateTessEvalShader (const ShaderSpec& shaderSpec);
2759 TessEvaluationExecutor::TessEvaluationExecutor (Context& context, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2760 : TessellationExecutor (context, shaderSpec, extraResourcesLayout)
2764 TessEvaluationExecutor::~TessEvaluationExecutor (void)
2768 static std::string generatePassthroughTessControlShader (void)
2770 std::ostringstream src;
2772 src << "#version 310 es\n"
2773 "#extension GL_EXT_tessellation_shader : require\n\n";
2775 src << "layout(vertices = 1) out;\n\n";
2777 src << "void main (void)\n{\n";
2779 for (int ndx = 0; ndx < 2; ndx++)
2780 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2782 for (int ndx = 0; ndx < 4; ndx++)
2783 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2790 std::string TessEvaluationExecutor::generateTessEvalShader (const ShaderSpec& shaderSpec)
2792 std::ostringstream src;
2794 src << glu::getGLSLVersionDeclaration(shaderSpec.glslVersion) << "\n";
2796 if (shaderSpec.glslVersion == glu::GLSL_VERSION_310_ES)
2797 src << "#extension GL_EXT_tessellation_shader : require\n\n";
2799 if (!shaderSpec.globalDeclarations.empty())
2800 src << shaderSpec.globalDeclarations << "\n";
2804 src << "layout(isolines, equal_spacing) in;\n\n";
2806 declareBufferBlocks(src, shaderSpec);
2808 src << "void main (void)\n{\n"
2809 << "\tgl_Position = vec4(gl_TessCoord.x, 0.0, 0.0, 1.0);\n"
2810 << "\thighp uint invocationId = uint(gl_PrimitiveID)*2u + (gl_TessCoord.x > 0.5 ? 1u : 0u);\n";
2812 generateExecBufferIo(src, shaderSpec, "invocationId");
2819 void TessEvaluationExecutor::generateSources (const ShaderSpec& shaderSpec, SourceCollections& programCollection)
2821 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess()) << shaderSpec.buildOptions;
2822 programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generatePassthroughTessControlShader()) << shaderSpec.buildOptions;
2823 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateTessEvalShader(shaderSpec)) << shaderSpec.buildOptions;
2824 programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource()) << shaderSpec.buildOptions;
2827 void TessEvaluationExecutor::execute (int numValues, const void* const* inputs, void* const* outputs, VkDescriptorSet extraResources)
2829 const int patchSize = 2;
2830 const int alignedValues = deAlign32(numValues, patchSize);
2832 // Initialize buffers with aligned value count to make room for padding
2833 initBuffers(alignedValues);
2835 // Setup input buffer & copy data
2836 uploadInputBuffer(inputs, numValues);
2838 renderTess((deUint32)alignedValues, (deUint32)alignedValues, (deUint32)patchSize, extraResources);
2841 readOutputBuffer(outputs, numValues);
2848 ShaderExecutor::~ShaderExecutor (void)
2854 void generateSources (glu::ShaderType shaderType, const ShaderSpec& shaderSpec, vk::SourceCollections& dst)
2858 case glu::SHADERTYPE_VERTEX: VertexShaderExecutor::generateSources (shaderSpec, dst); break;
2859 case glu::SHADERTYPE_TESSELLATION_CONTROL: TessControlExecutor::generateSources (shaderSpec, dst); break;
2860 case glu::SHADERTYPE_TESSELLATION_EVALUATION: TessEvaluationExecutor::generateSources (shaderSpec, dst); break;
2861 case glu::SHADERTYPE_GEOMETRY: GeometryShaderExecutor::generateSources (shaderSpec, dst); break;
2862 case glu::SHADERTYPE_FRAGMENT: FragmentShaderExecutor::generateSources (shaderSpec, dst); break;
2863 case glu::SHADERTYPE_COMPUTE: ComputeShaderExecutor::generateSources (shaderSpec, dst); break;
2865 TCU_THROW(InternalError, "Unsupported shader type");
2869 ShaderExecutor* createExecutor (Context& context, glu::ShaderType shaderType, const ShaderSpec& shaderSpec, VkDescriptorSetLayout extraResourcesLayout)
2873 case glu::SHADERTYPE_VERTEX: return new VertexShaderExecutor (context, shaderSpec, extraResourcesLayout);
2874 case glu::SHADERTYPE_TESSELLATION_CONTROL: return new TessControlExecutor (context, shaderSpec, extraResourcesLayout);
2875 case glu::SHADERTYPE_TESSELLATION_EVALUATION: return new TessEvaluationExecutor (context, shaderSpec, extraResourcesLayout);
2876 case glu::SHADERTYPE_GEOMETRY: return new GeometryShaderExecutor (context, shaderSpec, extraResourcesLayout);
2877 case glu::SHADERTYPE_FRAGMENT: return new FragmentShaderExecutor (context, shaderSpec, extraResourcesLayout);
2878 case glu::SHADERTYPE_COMPUTE: return new ComputeShaderExecutor (context, shaderSpec, extraResourcesLayout);
2880 TCU_THROW(InternalError, "Unsupported shader type");