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"
31 #include "tcuVector.hpp"
32 #include "tcuTestLog.hpp"
33 #include "tcuFormatUtil.hpp"
34 #include "tcuTextureUtil.hpp"
35 #include "deUniquePtr.hpp"
36 #include "deStringUtil.hpp"
37 #include "deSharedPtr.hpp"
39 #include "vkMemUtil.hpp"
41 #include "vkPlatform.hpp"
42 #include "vkPrograms.hpp"
43 #include "vkStrUtil.hpp"
44 #include "vkRefUtil.hpp"
45 #include "vkTypeUtil.hpp"
46 #include "vkQueryUtil.hpp"
47 #include "vkDeviceUtil.hpp"
48 #include "vkImageUtil.hpp"
50 #include "gluShaderUtil.hpp"
57 namespace shaderexecutor
64 DEFAULT_RENDER_WIDTH = 100,
65 DEFAULT_RENDER_HEIGHT = 100,
70 static VkClearValue getDefaultClearColor (void)
72 return makeClearValueColorF32(0.125f, 0.25f, 0.5f, 1.0f);
75 static void checkSupported (const Context& ctx, glu::ShaderType shaderType)
77 const VkPhysicalDeviceFeatures& features = ctx.getDeviceFeatures();
79 if (shaderType == glu::SHADERTYPE_GEOMETRY && !features.geometryShader)
80 TCU_THROW(NotSupportedError, "Geometry shader type not supported by device");
81 else if (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL && !features.tessellationShader)
82 TCU_THROW(NotSupportedError, "Tessellation shader type not supported by device");
83 else if (shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION && !features.tessellationShader)
84 TCU_THROW(NotSupportedError, "Tessellation shader type not supported by device");
87 static std::string generateEmptyFragmentSource ()
89 std::ostringstream src;
91 src << "#version 310 es\n"
92 "layout(location=0) out highp vec4 o_color;\n";
94 src << "void main (void)\n{\n";
95 src << " o_color = vec4(0.0);\n";
101 static std::string generatePassthroughVertexShader (const std::vector<Symbol>& inputs, const char* inputPrefix, const char* outputPrefix)
104 std::ostringstream src;
107 src << "#version 310 es\n"
108 "layout(location = " << location << ") in highp vec4 a_position;\n";
110 for (vector<Symbol>::const_iterator input = inputs.begin(); input != inputs.end(); ++input)
113 src << "layout(location = "<< location << ") in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n"
114 << "layout(location = " << location - 1 << ") flat out " << glu::declare(input->varType, outputPrefix + input->name) << ";\n";
117 src << "\nvoid main (void)\n{\n"
118 << " gl_Position = a_position;\n"
119 << " gl_PointSize = 1.0;\n";
121 for (vector<Symbol>::const_iterator input = inputs.begin(); input != inputs.end(); ++input)
122 src << "\t" << outputPrefix << input->name << " = " << inputPrefix << input->name << ";\n";
129 static std::string generateVertexShader (const ShaderSpec& shaderSpec, const std::string& inputPrefix, const std::string& outputPrefix)
131 DE_ASSERT(!inputPrefix.empty() && !outputPrefix.empty());
133 std::ostringstream src;
135 src << "#version 310 es\n";
137 if (!shaderSpec.globalDeclarations.empty())
138 src << shaderSpec.globalDeclarations << "\n";
140 src << "layout(location = 0) in highp vec4 a_position;\n";
142 int locationNumber = 1;
143 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber)
144 src << "layout(location = " << locationNumber << ") in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n";
147 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber)
149 DE_ASSERT(output->varType.isBasicType());
151 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
153 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
154 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
155 const glu::VarType intType (intBaseType, glu::PRECISION_HIGHP);
157 src << "layout(location = " << locationNumber << ") flat out " << glu::declare(intType, outputPrefix + output->name) << ";\n";
160 src << "layout(location = " << locationNumber << ") flat out " << glu::declare(output->varType, outputPrefix + output->name) << ";\n";
164 << "void main (void)\n"
166 << " gl_Position = a_position;\n"
167 << " gl_PointSize = 1.0;\n";
169 // Declare & fetch local input variables
170 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input)
171 src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << ";\n";
173 // Declare local output variables
174 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
175 src << "\t" << glu::declare(output->varType, output->name) << ";\n";
177 // Operation - indented to correct level.
179 std::istringstream opSrc (shaderSpec.source);
182 while (std::getline(opSrc, line))
183 src << "\t" << line << "\n";
186 // Assignments to outputs.
187 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
189 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
191 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
192 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
194 src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << output->name << ");\n";
197 src << "\t" << outputPrefix << output->name << " = " << output->name << ";\n";
205 struct FragmentOutputLayout
207 std::vector<const Symbol*> locationSymbols; //! Symbols by location
208 std::map<std::string, int> locationMap; //! Map from symbol name to start location
211 static void generateFragShaderOutputDecl (std::ostream& src, const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& outputPrefix)
213 for (int outNdx = 0; outNdx < (int)shaderSpec.outputs.size(); ++outNdx)
215 const Symbol& output = shaderSpec.outputs[outNdx];
216 const int location = de::lookup(outLocationMap, output.name);
217 const std::string outVarName = outputPrefix + output.name;
218 glu::VariableDeclaration decl (output.varType, outVarName, glu::STORAGE_OUT, glu::INTERPOLATION_LAST, glu::Layout(location));
220 TCU_CHECK_INTERNAL(output.varType.isBasicType());
222 if (useIntOutputs && glu::isDataTypeFloatOrVec(output.varType.getBasicType()))
224 const int vecSize = glu::getDataTypeScalarSize(output.varType.getBasicType());
225 const glu::DataType uintBasicType = vecSize > 1 ? glu::getDataTypeUintVec(vecSize) : glu::TYPE_UINT;
226 const glu::VarType uintType (uintBasicType, glu::PRECISION_HIGHP);
228 decl.varType = uintType;
229 src << decl << ";\n";
231 else if (glu::isDataTypeBoolOrBVec(output.varType.getBasicType()))
233 const int vecSize = glu::getDataTypeScalarSize(output.varType.getBasicType());
234 const glu::DataType intBasicType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
235 const glu::VarType intType (intBasicType, glu::PRECISION_HIGHP);
237 decl.varType = intType;
238 src << decl << ";\n";
240 else if (glu::isDataTypeMatrix(output.varType.getBasicType()))
242 const int vecSize = glu::getDataTypeMatrixNumRows(output.varType.getBasicType());
243 const int numVecs = glu::getDataTypeMatrixNumColumns(output.varType.getBasicType());
244 const glu::DataType uintBasicType = glu::getDataTypeUintVec(vecSize);
245 const glu::VarType uintType (uintBasicType, glu::PRECISION_HIGHP);
247 decl.varType = uintType;
248 for (int vecNdx = 0; vecNdx < numVecs; ++vecNdx)
250 decl.name = outVarName + "_" + de::toString(vecNdx);
251 decl.layout.location = location + vecNdx;
252 src << decl << ";\n";
256 src << decl << ";\n";
260 static void generateFragShaderOutAssign (std::ostream& src, const ShaderSpec& shaderSpec, bool useIntOutputs, const std::string& valuePrefix, const std::string& outputPrefix)
262 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
264 if (useIntOutputs && glu::isDataTypeFloatOrVec(output->varType.getBasicType()))
265 src << " o_" << output->name << " = floatBitsToUint(" << valuePrefix << output->name << ");\n";
266 else if (glu::isDataTypeMatrix(output->varType.getBasicType()))
268 const int numVecs = glu::getDataTypeMatrixNumColumns(output->varType.getBasicType());
270 for (int vecNdx = 0; vecNdx < numVecs; ++vecNdx)
272 src << "\t" << outputPrefix << output->name << "_" << vecNdx << " = floatBitsToUint(" << valuePrefix << output->name << "[" << vecNdx << "]);\n";
274 src << "\t" << outputPrefix << output->name << "_" << vecNdx << " = " << valuePrefix << output->name << "[" << vecNdx << "];\n";
276 else if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
278 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
279 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
281 src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << valuePrefix << output->name << ");\n";
284 src << "\t" << outputPrefix << output->name << " = " << valuePrefix << output->name << ";\n";
288 static std::string generatePassthroughFragmentShader (const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& inputPrefix, const std::string& outputPrefix)
290 std::ostringstream src;
292 src << "#version 310 es\n";
294 if (!shaderSpec.globalDeclarations.empty())
295 src << shaderSpec.globalDeclarations << "\n";
297 int locationNumber = 0;
298 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber)
300 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
302 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
303 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
304 const glu::VarType intType (intBaseType, glu::PRECISION_HIGHP);
306 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(intType, inputPrefix + output->name) << ";\n";
309 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(output->varType, inputPrefix + output->name) << ";\n";
312 generateFragShaderOutputDecl(src, shaderSpec, useIntOutputs, outLocationMap, outputPrefix);
314 src << "\nvoid main (void)\n{\n";
316 generateFragShaderOutAssign(src, shaderSpec, useIntOutputs, inputPrefix, outputPrefix);
323 static std::string generateGeometryShader (const ShaderSpec& shaderSpec, const std::string& inputPrefix, const std::string& outputPrefix)
325 DE_ASSERT(!inputPrefix.empty() && !outputPrefix.empty());
327 std::ostringstream src;
329 src << "#version 310 es\n"
330 "#extension GL_EXT_geometry_shader : require\n";
332 if (!shaderSpec.globalDeclarations.empty())
333 src << shaderSpec.globalDeclarations << "\n";
335 src << "layout(points) in;\n"
336 << "layout(points, max_vertices = 1) out;\n";
338 int locationNumber = 0;
339 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber)
340 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(input->varType, inputPrefix + input->name) << "[];\n";
343 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber)
345 DE_ASSERT(output->varType.isBasicType());
347 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
349 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
350 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
351 const glu::VarType intType (intBaseType, glu::PRECISION_HIGHP);
353 src << "layout(location = " << locationNumber << ") flat out " << glu::declare(intType, outputPrefix + output->name) << ";\n";
356 src << "layout(location = " << locationNumber << ") flat out " << glu::declare(output->varType, outputPrefix + output->name) << ";\n";
360 << "void main (void)\n"
362 << " gl_Position = gl_in[0].gl_Position;\n\n";
364 // Fetch input variables
365 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input)
366 src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << "[0];\n";
368 // Declare local output variables.
369 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
370 src << "\t" << glu::declare(output->varType, output->name) << ";\n";
374 // Operation - indented to correct level.
376 std::istringstream opSrc (shaderSpec.source);
379 while (std::getline(opSrc, line))
380 src << "\t" << line << "\n";
383 // Assignments to outputs.
384 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
386 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
388 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
389 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
391 src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << output->name << ");\n";
394 src << "\t" << outputPrefix << output->name << " = " << output->name << ";\n";
397 src << " EmitVertex();\n"
398 << " EndPrimitive();\n"
404 static std::string generateFragmentShader (const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& inputPrefix, const std::string& outputPrefix)
406 std::ostringstream src;
407 src << "#version 310 es\n";
408 if (!shaderSpec.globalDeclarations.empty())
409 src << shaderSpec.globalDeclarations << "\n";
411 int locationNumber = 0;
412 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber)
413 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n";
415 generateFragShaderOutputDecl(src, shaderSpec, useIntOutputs, outLocationMap, outputPrefix);
417 src << "\nvoid main (void)\n{\n";
419 // Declare & fetch local input variables
420 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input)
421 src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << ";\n";
423 // Declare output variables
424 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
425 src << "\t" << glu::declare(output->varType, output->name) << ";\n";
427 // Operation - indented to correct level.
429 std::istringstream opSrc (shaderSpec.source);
432 while (std::getline(opSrc, line))
433 src << "\t" << line << "\n";
436 generateFragShaderOutAssign(src, shaderSpec, useIntOutputs, "", outputPrefix);
443 // FragmentOutExecutor
445 class FragmentOutExecutor : public ShaderExecutor
448 FragmentOutExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
449 virtual ~FragmentOutExecutor (void);
451 virtual void execute (const Context& ctx,
453 const void* const* inputs,
454 void* const* outputs);
457 const FragmentOutputLayout m_outputLayout;
459 void bindAttributes (const Context& ctx,
462 const void* const* inputs);
464 void addAttribute (const Context& ctx,
466 deUint32 bindingLocation,
468 deUint32 sizePerElement,
470 const void* dataPtr);
471 // reinit render data members
472 virtual void clearRenderData (void);
474 typedef de::SharedPtr<Unique<VkImage> > VkImageSp;
475 typedef de::SharedPtr<Unique<VkImageView> > VkImageViewSp;
476 typedef de::SharedPtr<Unique<VkBuffer> > VkBufferSp;
477 typedef de::SharedPtr<de::UniquePtr<Allocation> > AllocationSp;
479 std::vector<VkVertexInputBindingDescription> m_vertexBindingDescriptions;
480 std::vector<VkVertexInputAttributeDescription> m_vertexAttributeDescriptions;
481 std::vector<VkBufferSp> m_vertexBuffers;
482 std::vector<AllocationSp> m_vertexBufferAllocs;
485 static FragmentOutputLayout computeFragmentOutputLayout (const std::vector<Symbol>& symbols)
487 FragmentOutputLayout ret;
490 for (std::vector<Symbol>::const_iterator it = symbols.begin(); it != symbols.end(); ++it)
492 const int numLocations = glu::getDataTypeNumLocations(it->varType.getBasicType());
494 TCU_CHECK_INTERNAL(!de::contains(ret.locationMap, it->name));
495 de::insert(ret.locationMap, it->name, location);
496 location += numLocations;
498 for (int ndx = 0; ndx < numLocations; ++ndx)
499 ret.locationSymbols.push_back(&*it);
505 FragmentOutExecutor::FragmentOutExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
506 : ShaderExecutor (shaderSpec, shaderType)
507 , m_outputLayout (computeFragmentOutputLayout(m_shaderSpec.outputs))
511 FragmentOutExecutor::~FragmentOutExecutor (void)
515 static std::vector<tcu::Vec2> computeVertexPositions (int numValues, const tcu::IVec2& renderSize)
517 std::vector<tcu::Vec2> positions(numValues);
518 for (int valNdx = 0; valNdx < numValues; valNdx++)
520 const int ix = valNdx % renderSize.x();
521 const int iy = valNdx / renderSize.x();
522 const float fx = -1.0f + 2.0f*((float(ix) + 0.5f) / float(renderSize.x()));
523 const float fy = -1.0f + 2.0f*((float(iy) + 0.5f) / float(renderSize.y()));
525 positions[valNdx] = tcu::Vec2(fx, fy);
531 static tcu::TextureFormat getRenderbufferFormatForOutput (const glu::VarType& outputType, bool useIntOutputs)
533 const tcu::TextureFormat::ChannelOrder channelOrderMap[] =
535 tcu::TextureFormat::R,
536 tcu::TextureFormat::RG,
537 tcu::TextureFormat::RGBA, // No RGB variants available.
538 tcu::TextureFormat::RGBA
541 const glu::DataType basicType = outputType.getBasicType();
542 const int numComps = glu::getDataTypeNumComponents(basicType);
543 tcu::TextureFormat::ChannelType channelType;
545 switch (glu::getDataTypeScalarType(basicType))
547 case glu::TYPE_UINT: channelType = tcu::TextureFormat::UNSIGNED_INT32; break;
548 case glu::TYPE_INT: channelType = tcu::TextureFormat::SIGNED_INT32; break;
549 case glu::TYPE_BOOL: channelType = tcu::TextureFormat::SIGNED_INT32; break;
550 case glu::TYPE_FLOAT: channelType = useIntOutputs ? tcu::TextureFormat::UNSIGNED_INT32 : tcu::TextureFormat::FLOAT; break;
552 throw tcu::InternalError("Invalid output type");
555 DE_ASSERT(de::inRange<int>(numComps, 1, DE_LENGTH_OF_ARRAY(channelOrderMap)));
557 return tcu::TextureFormat(channelOrderMap[numComps-1], channelType);
560 static VkFormat getAttributeFormat (const glu::DataType dataType)
564 case glu::TYPE_FLOAT: return VK_FORMAT_R32_SFLOAT;
565 case glu::TYPE_FLOAT_VEC2: return VK_FORMAT_R32G32_SFLOAT;
566 case glu::TYPE_FLOAT_VEC3: return VK_FORMAT_R32G32B32_SFLOAT;
567 case glu::TYPE_FLOAT_VEC4: return VK_FORMAT_R32G32B32A32_SFLOAT;
569 case glu::TYPE_INT: return VK_FORMAT_R32_SINT;
570 case glu::TYPE_INT_VEC2: return VK_FORMAT_R32G32_SINT;
571 case glu::TYPE_INT_VEC3: return VK_FORMAT_R32G32B32_SINT;
572 case glu::TYPE_INT_VEC4: return VK_FORMAT_R32G32B32A32_SINT;
574 case glu::TYPE_UINT: return VK_FORMAT_R32_UINT;
575 case glu::TYPE_UINT_VEC2: return VK_FORMAT_R32G32_UINT;
576 case glu::TYPE_UINT_VEC3: return VK_FORMAT_R32G32B32_UINT;
577 case glu::TYPE_UINT_VEC4: return VK_FORMAT_R32G32B32A32_UINT;
579 case glu::TYPE_FLOAT_MAT2: return VK_FORMAT_R32G32_SFLOAT;
580 case glu::TYPE_FLOAT_MAT2X3: return VK_FORMAT_R32G32B32_SFLOAT;
581 case glu::TYPE_FLOAT_MAT2X4: return VK_FORMAT_R32G32B32A32_SFLOAT;
582 case glu::TYPE_FLOAT_MAT3X2: return VK_FORMAT_R32G32_SFLOAT;
583 case glu::TYPE_FLOAT_MAT3: return VK_FORMAT_R32G32B32_SFLOAT;
584 case glu::TYPE_FLOAT_MAT3X4: return VK_FORMAT_R32G32B32A32_SFLOAT;
585 case glu::TYPE_FLOAT_MAT4X2: return VK_FORMAT_R32G32_SFLOAT;
586 case glu::TYPE_FLOAT_MAT4X3: return VK_FORMAT_R32G32B32_SFLOAT;
587 case glu::TYPE_FLOAT_MAT4: return VK_FORMAT_R32G32B32A32_SFLOAT;
590 return VK_FORMAT_UNDEFINED;
594 void FragmentOutExecutor::addAttribute (const Context& ctx, Allocator& memAlloc, deUint32 bindingLocation, VkFormat format, deUint32 sizePerElement, deUint32 count, const void* dataPtr)
596 // Add binding specification
597 const deUint32 binding = (deUint32)m_vertexBindingDescriptions.size();
598 const VkVertexInputBindingDescription bindingDescription =
602 VK_VERTEX_INPUT_RATE_VERTEX
605 m_vertexBindingDescriptions.push_back(bindingDescription);
607 // Add location and format specification
608 const VkVertexInputAttributeDescription attributeDescription =
610 bindingLocation, // deUint32 location;
611 binding, // deUint32 binding;
612 format, // VkFormat format;
613 0u, // deUint32 offsetInBytes;
616 m_vertexAttributeDescriptions.push_back(attributeDescription);
618 // Upload data to buffer
619 const VkDevice vkDevice = ctx.getDevice();
620 const DeviceInterface& vk = ctx.getDeviceInterface();
621 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex();
623 const VkDeviceSize inputSize = sizePerElement * count;
624 const VkBufferCreateInfo vertexBufferParams =
626 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
627 DE_NULL, // const void* pNext;
628 0u, // VkBufferCreateFlags flags;
629 inputSize, // VkDeviceSize size;
630 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
631 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
632 1u, // deUint32 queueFamilyCount;
633 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
636 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &vertexBufferParams);
637 de::MovePtr<Allocation> alloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
638 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
640 deMemcpy(alloc->getHostPtr(), dataPtr, (size_t)inputSize);
641 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), inputSize);
643 m_vertexBuffers.push_back(de::SharedPtr<Unique<VkBuffer> >(new Unique<VkBuffer>(buffer)));
644 m_vertexBufferAllocs.push_back(de::SharedPtr<de::UniquePtr<Allocation> >(new de::UniquePtr<Allocation>(alloc)));
647 void FragmentOutExecutor::bindAttributes (const Context& ctx, Allocator& memAlloc, int numValues, const void* const* inputs)
650 for (int inputNdx = 0; inputNdx < (int)m_shaderSpec.inputs.size(); inputNdx++)
652 const Symbol& symbol = m_shaderSpec.inputs[inputNdx];
653 const void* ptr = inputs[inputNdx];
654 const glu::DataType basicType = symbol.varType.getBasicType();
655 const int vecSize = glu::getDataTypeScalarSize(basicType);
656 const VkFormat format = getAttributeFormat(basicType);
658 int numAttrsToAdd = 1;
660 if (glu::isDataTypeFloatOrVec(basicType))
661 elementSize = sizeof(float);
662 else if (glu::isDataTypeIntOrIVec(basicType))
663 elementSize = sizeof(int);
664 else if (glu::isDataTypeUintOrUVec(basicType))
665 elementSize = sizeof(deUint32);
666 else if (glu::isDataTypeMatrix(basicType))
668 int numRows = glu::getDataTypeMatrixNumRows(basicType);
669 int numCols = glu::getDataTypeMatrixNumColumns(basicType);
671 elementSize = numRows * numCols * (int)sizeof(float);
672 numAttrsToAdd = numCols;
677 // add attributes, in case of matrix every column is binded as an attribute
678 for (int attrNdx = 0; attrNdx < numAttrsToAdd; attrNdx++)
680 addAttribute(ctx, memAlloc, (deUint32)m_vertexBindingDescriptions.size(), format, elementSize * vecSize, numValues, ptr);
685 void FragmentOutExecutor::clearRenderData (void)
687 m_vertexBindingDescriptions.clear();
688 m_vertexAttributeDescriptions.clear();
689 m_vertexBuffers.clear();
690 m_vertexBufferAllocs.clear();
693 void FragmentOutExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs)
695 checkSupported(ctx, m_shaderType);
697 const VkDevice vkDevice = ctx.getDevice();
698 const DeviceInterface& vk = ctx.getDeviceInterface();
699 const VkQueue queue = ctx.getUniversalQueue();
700 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex();
701 Allocator& memAlloc = ctx.getDefaultAllocator();
703 const deUint32 renderSizeX = de::min(static_cast<deUint32>(DEFAULT_RENDER_WIDTH), (deUint32)numValues);
704 const deUint32 renderSizeY = ((deUint32)numValues / renderSizeX) + (((deUint32)numValues % renderSizeX != 0) ? 1u : 0u);
705 const tcu::UVec2 renderSize (renderSizeX, renderSizeY);
706 std::vector<tcu::Vec2> positions;
708 const bool useGeometryShader = m_shaderType == glu::SHADERTYPE_GEOMETRY;
710 std::vector<VkImageSp> colorImages;
711 std::vector<VkImageMemoryBarrier> colorImagePreRenderBarriers;
712 std::vector<VkImageMemoryBarrier> colorImagePostRenderBarriers;
713 std::vector<AllocationSp> colorImageAllocs;
714 std::vector<VkAttachmentDescription> attachments;
715 std::vector<VkClearValue> attachmentClearValues;
716 std::vector<VkImageViewSp> colorImageViews;
718 std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentStates;
719 std::vector<VkAttachmentReference> colorAttachmentReferences;
721 Move<VkRenderPass> renderPass;
722 Move<VkFramebuffer> framebuffer;
723 Move<VkPipelineLayout> pipelineLayout;
724 Move<VkPipeline> graphicsPipeline;
726 Move<VkShaderModule> vertexShaderModule;
727 Move<VkShaderModule> geometryShaderModule;
728 Move<VkShaderModule> fragmentShaderModule;
730 Move<VkCommandPool> cmdPool;
731 Move<VkCommandBuffer> cmdBuffer;
735 Move<VkDescriptorPool> descriptorPool;
736 Move<VkDescriptorSetLayout> descriptorSetLayout;
737 Move<VkDescriptorSet> descriptorSet;
741 // Compute positions - 1px points are used to drive fragment shading.
742 positions = computeVertexPositions(numValues, renderSize.cast<int>());
745 addAttribute(ctx, memAlloc, 0u, VK_FORMAT_R32G32_SFLOAT, sizeof(tcu::Vec2), (deUint32)positions.size(), &positions[0]);
746 bindAttributes(ctx, memAlloc, numValues, inputs);
748 // Create color images
750 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
752 VK_FALSE, // VkBool32 blendEnable;
753 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
754 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
755 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
756 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
757 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destAlphaBlendFactor;
758 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
759 (VK_COLOR_COMPONENT_R_BIT |
760 VK_COLOR_COMPONENT_G_BIT |
761 VK_COLOR_COMPONENT_B_BIT |
762 VK_COLOR_COMPONENT_A_BIT) // VkColorComponentFlags colorWriteMask;
765 for (int outNdx = 0; outNdx < (int)m_outputLayout.locationSymbols.size(); ++outNdx)
767 const bool isFloat = isDataTypeFloatOrVec(m_shaderSpec.outputs[outNdx].varType.getBasicType());
768 const bool isSigned = isDataTypeIntOrIVec (m_shaderSpec.outputs[outNdx].varType.getBasicType());
769 const bool isBool = isDataTypeBoolOrBVec(m_shaderSpec.outputs[outNdx].varType.getBasicType());
770 const VkFormat colorFormat = isFloat ? VK_FORMAT_R32G32B32A32_SFLOAT : (isSigned || isBool ? VK_FORMAT_R32G32B32A32_SINT : VK_FORMAT_R32G32B32A32_UINT);
772 const VkImageCreateInfo colorImageParams =
774 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
775 DE_NULL, // const void* pNext;
776 0u, // VkImageCreateFlags flags;
777 VK_IMAGE_TYPE_2D, // VkImageType imageType;
778 colorFormat, // VkFormat format;
779 { renderSize.x(), renderSize.y(), 1u }, // VkExtent3D extent;
780 1u, // deUint32 mipLevels;
781 1u, // deUint32 arraySize;
782 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
783 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
784 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
785 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
786 1u, // deUint32 queueFamilyCount;
787 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
788 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
791 const VkAttachmentDescription colorAttachmentDescription =
793 0u, // VkAttachmentDescriptorFlags flags;
794 colorFormat, // VkFormat format;
795 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
796 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
797 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
798 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
799 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
800 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
801 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
804 Move<VkImage> colorImage = createImage(vk, vkDevice, &colorImageParams);
805 colorImages.push_back(de::SharedPtr<Unique<VkImage> >(new Unique<VkImage>(colorImage)));
806 attachmentClearValues.push_back(getDefaultClearColor());
808 // Allocate and bind color image memory
810 de::MovePtr<Allocation> colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *((const VkImage*) colorImages.back().get())), MemoryRequirement::Any);
811 VK_CHECK(vk.bindImageMemory(vkDevice, colorImages.back().get()->get(), colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
812 colorImageAllocs.push_back(de::SharedPtr<de::UniquePtr<Allocation> >(new de::UniquePtr<Allocation>(colorImageAlloc)));
814 attachments.push_back(colorAttachmentDescription);
815 colorBlendAttachmentStates.push_back(colorBlendAttachmentState);
817 const VkAttachmentReference colorAttachmentReference = {
818 (deUint32) (colorImages.size() - 1), // deUint32 attachment;
819 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
822 colorAttachmentReferences.push_back(colorAttachmentReference);
825 // Create color attachment view
827 const VkImageViewCreateInfo colorImageViewParams =
829 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
830 DE_NULL, // const void* pNext;
831 0u, // VkImageViewCreateFlags flags;
832 colorImages.back().get()->get(), // VkImage image;
833 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
834 colorFormat, // VkFormat format;
836 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
837 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
838 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
839 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
840 }, // VkComponentMapping components;
842 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
843 0u, // deUint32 baseMipLevel;
844 1u, // deUint32 mipLevels;
845 0u, // deUint32 baseArraySlice;
846 1u // deUint32 arraySize;
847 } // VkImageSubresourceRange subresourceRange;
850 Move<VkImageView> colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
851 colorImageViews.push_back(de::SharedPtr<Unique<VkImageView> >(new Unique<VkImageView>(colorImageView)));
853 const VkImageMemoryBarrier colorImagePreRenderBarrier =
855 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
858 (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
859 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), // dstAccessMask
860 VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
861 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
862 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
863 VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex
864 colorImages.back().get()->get(), // image
866 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
869 0u, // baseArrayLayer
871 } // subresourceRange
873 colorImagePreRenderBarriers.push_back(colorImagePreRenderBarrier);
875 const VkImageMemoryBarrier colorImagePostRenderBarrier =
877 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
879 (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
880 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), // srcAccessMask
881 VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask
882 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout
883 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
884 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
885 VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex
886 colorImages.back().get()->get(), // image
888 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
891 0u, // baseArrayLayer
893 } // subresourceRange
895 colorImagePostRenderBarriers.push_back(colorImagePostRenderBarrier);
900 // Create render pass
902 const VkSubpassDescription subpassDescription =
904 0u, // VkSubpassDescriptionFlags flags;
905 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
906 0u, // deUint32 inputCount;
907 DE_NULL, // const VkAttachmentReference* pInputAttachments;
908 (deUint32)colorImages.size(), // deUint32 colorCount;
909 &colorAttachmentReferences[0], // const VkAttachmentReference* colorAttachments;
910 DE_NULL, // const VkAttachmentReference* resolveAttachments;
911 DE_NULL, // VkAttachmentReference depthStencilAttachment;
912 0u, // deUint32 preserveCount;
913 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
916 const VkRenderPassCreateInfo renderPassParams =
918 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
919 DE_NULL, // const void* pNext;
920 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
921 (deUint32)attachments.size(), // deUint32 attachmentCount;
922 &attachments[0], // const VkAttachmentDescription* pAttachments;
923 1u, // deUint32 subpassCount;
924 &subpassDescription, // const VkSubpassDescription* pSubpasses;
925 0u, // deUint32 dependencyCount;
926 DE_NULL // const VkSubpassDependency* pDependencies;
929 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
932 // Create framebuffer
934 std::vector<VkImageView> views(colorImageViews.size());
935 for (size_t i = 0; i < colorImageViews.size(); i++)
937 views[i] = colorImageViews[i].get()->get();
940 const VkFramebufferCreateInfo framebufferParams =
942 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
943 DE_NULL, // const void* pNext;
944 0u, // VkFramebufferCreateFlags flags;
945 *renderPass, // VkRenderPass renderPass;
946 (deUint32)views.size(), // deUint32 attachmentCount;
947 &views[0], // const VkImageView* pAttachments;
948 (deUint32)renderSize.x(), // deUint32 width;
949 (deUint32)renderSize.y(), // deUint32 height;
950 1u // deUint32 layers;
953 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
956 // Create descriptors
958 addUniforms(vkDevice, vk, queue, queueFamilyIndex, memAlloc);
960 descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
961 if (!m_uniformInfos.empty())
962 descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
965 const VkDescriptorPoolSize poolSizeCount = { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1 };
966 const VkDescriptorPoolCreateInfo createInfo =
968 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
970 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
976 descriptorPool = createDescriptorPool(vk, vkDevice, &createInfo);
979 const VkDescriptorSetAllocateInfo allocInfo =
981 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
985 &*descriptorSetLayout
988 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
990 // Update descriptors
992 vk::DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
994 uploadUniforms(descriptorSetUpdateBuilder, *descriptorSet);
996 descriptorSetUpdateBuilder.update(vk, vkDevice);
1000 // Create pipeline layout
1002 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1004 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1005 DE_NULL, // const void* pNext;
1006 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
1007 1, // deUint32 descriptorSetCount;
1008 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
1009 0u, // deUint32 pushConstantRangeCount;
1010 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1013 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1018 vertexShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("vert"), 0);
1019 fragmentShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("frag"), 0);
1021 if (useGeometryShader)
1023 geometryShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("geom"), 0);
1029 std::vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
1031 const VkPipelineShaderStageCreateInfo vertexShaderStageParams =
1033 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1034 DE_NULL, // const void* pNext;
1035 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
1036 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
1037 *vertexShaderModule, // VkShaderModule module;
1038 "main", // const char* pName;
1039 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1042 const VkPipelineShaderStageCreateInfo fragmentShaderStageParams =
1044 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1045 DE_NULL, // const void* pNext;
1046 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
1047 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
1048 *fragmentShaderModule, // VkShaderModule module;
1049 "main", // const char* pName;
1050 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1053 shaderStageParams.push_back(vertexShaderStageParams);
1054 shaderStageParams.push_back(fragmentShaderStageParams);
1056 if (useGeometryShader)
1058 const VkPipelineShaderStageCreateInfo geometryShaderStageParams =
1060 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1061 DE_NULL, // const void* pNext;
1062 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
1063 VK_SHADER_STAGE_GEOMETRY_BIT, // VkShaderStageFlagBits stage;
1064 *geometryShaderModule, // VkShaderModule module;
1065 "main", // VkShader shader;
1066 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1069 shaderStageParams.push_back(geometryShaderStageParams);
1072 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1074 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1075 DE_NULL, // const void* pNext;
1076 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
1077 (deUint32)m_vertexBindingDescriptions.size(), // deUint32 bindingCount;
1078 &m_vertexBindingDescriptions[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1079 (deUint32)m_vertexAttributeDescriptions.size(), // deUint32 attributeCount;
1080 &m_vertexAttributeDescriptions[0], // const VkVertexInputAttributeDescription* pvertexAttributeDescriptions;
1083 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
1085 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1086 DE_NULL, // const void* pNext;
1087 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
1088 VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // VkPrimitiveTopology topology;
1089 DE_FALSE // VkBool32 primitiveRestartEnable;
1092 const VkViewport viewport =
1094 0.0f, // float originX;
1095 0.0f, // float originY;
1096 (float)renderSize.x(), // float width;
1097 (float)renderSize.y(), // float height;
1098 0.0f, // float minDepth;
1099 1.0f // float maxDepth;
1102 const VkRect2D scissor =
1107 }, // VkOffset2D offset;
1109 renderSize.x(), // deUint32 width;
1110 renderSize.y(), // deUint32 height;
1111 }, // VkExtent2D extent;
1114 const VkPipelineViewportStateCreateInfo viewportStateParams =
1116 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
1117 DE_NULL, // const void* pNext;
1118 0u, // VkPipelineViewportStateCreateFlags flags;
1119 1u, // deUint32 viewportCount;
1120 &viewport, // const VkViewport* pViewports;
1121 1u, // deUint32 scissorsCount;
1122 &scissor // const VkRect2D* pScissors;
1125 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
1127 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1128 DE_NULL, // const void* pNext;
1129 (VkPipelineRasterizationStateCreateFlags)0u, //VkPipelineRasterizationStateCreateFlags flags;
1130 VK_FALSE, // VkBool32 depthClipEnable;
1131 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
1132 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
1133 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
1134 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
1135 VK_FALSE, // VkBool32 depthBiasEnable;
1136 0.0f, // float depthBias;
1137 0.0f, // float depthBiasClamp;
1138 0.0f, // float slopeScaledDepthBias;
1139 1.0f // float lineWidth;
1142 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1144 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1145 DE_NULL, // const void* pNext;
1146 0u, // VkPipelineMultisampleStateCreateFlags flags;
1147 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
1148 VK_FALSE, // VkBool32 sampleShadingEnable;
1149 0.0f, // float minSampleShading;
1150 DE_NULL, // const VkSampleMask* pSampleMask;
1151 VK_FALSE, // VkBool32 alphaToCoverageEnable;
1152 VK_FALSE // VkBool32 alphaToOneEnable;
1155 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1157 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1158 DE_NULL, // const void* pNext;
1159 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
1160 VK_FALSE, // VkBool32 logicOpEnable;
1161 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1162 (deUint32)colorBlendAttachmentStates.size(), // deUint32 attachmentCount;
1163 &colorBlendAttachmentStates[0], // const VkPipelineColorBlendAttachmentState* pAttachments;
1164 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConst[4];
1167 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1169 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1170 DE_NULL, // const void* pNext;
1171 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
1172 (deUint32)shaderStageParams.size(), // deUint32 stageCount;
1173 &shaderStageParams[0], // const VkPipelineShaderStageCreateInfo* pStages;
1174 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1175 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1176 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1177 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
1178 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
1179 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1180 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1181 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1182 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
1183 *pipelineLayout, // VkPipelineLayout layout;
1184 *renderPass, // VkRenderPass renderPass;
1185 0u, // deUint32 subpass;
1186 0u, // VkPipeline basePipelineHandle;
1187 0u // deInt32 basePipelineIndex;
1190 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1193 // Create command pool
1195 const VkCommandPoolCreateInfo cmdPoolParams =
1197 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
1198 DE_NULL, // const void* pNext;
1199 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
1200 queueFamilyIndex, // deUint32 queueFamilyIndex;
1203 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1206 // Create command buffer
1208 const VkCommandBufferAllocateInfo cmdBufferParams =
1210 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1211 DE_NULL, // const void* pNext;
1212 *cmdPool, // VkCmdPool cmdPool;
1213 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1214 1 // deUint32 bufferCount;
1217 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1219 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1220 DE_NULL, // const void* pNext;
1221 0u, // VkCmdBufferOptimizeFlags flags;
1222 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1225 const VkRenderPassBeginInfo renderPassBeginInfo =
1227 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1228 DE_NULL, // const void* pNext;
1229 *renderPass, // VkRenderPass renderPass;
1230 *framebuffer, // VkFramebuffer framebuffer;
1231 { { 0, 0 }, { renderSize.x(), renderSize.y() } }, // VkRect2D renderArea;
1232 (deUint32)attachmentClearValues.size(), // deUint32 attachmentCount;
1233 &attachmentClearValues[0] // const VkClearValue* pAttachmentClearValues;
1236 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
1238 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1240 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
1241 0, (const VkMemoryBarrier*)DE_NULL,
1242 0, (const VkBufferMemoryBarrier*)DE_NULL,
1243 (deUint32)colorImagePreRenderBarriers.size(), colorImagePreRenderBarriers.empty() ? DE_NULL : &colorImagePreRenderBarriers[0]);
1244 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1246 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
1247 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
1249 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
1251 std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
1253 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
1254 for (size_t i = 0; i < numberOfVertexAttributes; i++)
1256 buffers[i] = m_vertexBuffers[i].get()->get();
1259 vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
1260 vk.cmdDraw(*cmdBuffer, (deUint32)positions.size(), 1u, 0u, 0u);
1262 vk.cmdEndRenderPass(*cmdBuffer);
1263 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
1264 0, (const VkMemoryBarrier*)DE_NULL,
1265 0, (const VkBufferMemoryBarrier*)DE_NULL,
1266 (deUint32)colorImagePostRenderBarriers.size(), colorImagePostRenderBarriers.empty() ? DE_NULL : &colorImagePostRenderBarriers[0]);
1268 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1273 const VkFenceCreateInfo fenceParams =
1275 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
1276 DE_NULL, // const void* pNext;
1277 0u // VkFenceCreateFlags flags;
1280 fence = createFence(vk, vkDevice, &fenceParams);
1286 const VkSubmitInfo submitInfo =
1288 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
1290 0u, // waitSemaphoreCount
1291 DE_NULL, // pWaitSemaphores
1292 (const VkPipelineStageFlags*)DE_NULL,
1293 1u, // commandBufferCount
1294 &cmdBuffer.get(), // pCommandBuffers
1295 0u, // signalSemaphoreCount
1296 DE_NULL // pSignalSemaphores
1299 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1300 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1301 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), DE_TRUE, ~(0ull) /* infinity*/));
1304 // Read back result and output
1306 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(4 * sizeof(deUint32) * renderSize.x() * renderSize.y());
1307 const VkBufferCreateInfo readImageBufferParams =
1309 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1310 DE_NULL, // const void* pNext;
1311 0u, // VkBufferCreateFlags flags;
1312 imageSizeBytes, // VkDeviceSize size;
1313 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
1314 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1315 1u, // deUint32 queueFamilyCount;
1316 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1319 // constants for image copy
1321 const VkCommandPoolCreateInfo cmdPoolParams =
1323 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
1324 DE_NULL, // const void* pNext;
1325 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
1326 queueFamilyIndex // deUint32 queueFamilyIndex;
1329 Move<VkCommandPool> copyCmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1331 const VkCommandBufferAllocateInfo cmdBufferParams =
1333 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1334 DE_NULL, // const void* pNext;
1335 *copyCmdPool, // VkCmdPool cmdPool;
1336 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1337 1u // deUint32 bufferCount;
1340 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1342 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1343 DE_NULL, // const void* pNext;
1344 0u, // VkCmdBufferOptimizeFlags flags;
1345 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1348 const VkBufferImageCopy copyParams =
1350 0u, // VkDeviceSize bufferOffset;
1351 (deUint32)renderSize.x(), // deUint32 bufferRowLength;
1352 (deUint32)renderSize.y(), // deUint32 bufferImageHeight;
1354 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
1355 0u, // deUint32 mipLevel;
1356 0u, // deUint32 arraySlice;
1357 1u, // deUint32 arraySize;
1358 }, // VkImageSubresource imageSubresource;
1359 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
1360 { renderSize.x(), renderSize.y(), 1u } // VkExtent3D imageExtent;
1363 // Read back pixels.
1364 for (int outNdx = 0; outNdx < (int)m_shaderSpec.outputs.size(); ++outNdx)
1366 const Symbol& output = m_shaderSpec.outputs[outNdx];
1367 const int outSize = output.varType.getScalarSize();
1368 const int outVecSize = glu::getDataTypeNumComponents(output.varType.getBasicType());
1369 const int outNumLocs = glu::getDataTypeNumLocations(output.varType.getBasicType());
1370 deUint32* dstPtrBase = static_cast<deUint32*>(outputs[outNdx]);
1371 const int outLocation = de::lookup(m_outputLayout.locationMap, output.name);
1373 for (int locNdx = 0; locNdx < outNumLocs; ++locNdx)
1375 tcu::TextureLevel tmpBuf;
1376 const tcu::TextureFormat format = getRenderbufferFormatForOutput(output.varType, false);
1377 const tcu::TextureFormat readFormat (tcu::TextureFormat::RGBA, format.type);
1378 const Unique<VkBuffer> readImageBuffer(createBuffer(vk, vkDevice, &readImageBufferParams));
1379 const de::UniquePtr<Allocation> readImageBufferMemory(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
1381 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
1383 // Copy image to buffer
1386 Move<VkCommandBuffer> copyCmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
1388 const VkSubmitInfo submitInfo =
1390 VK_STRUCTURE_TYPE_SUBMIT_INFO,
1393 (const VkSemaphore*)DE_NULL,
1394 (const VkPipelineStageFlags*)DE_NULL,
1396 ©CmdBuffer.get(),
1398 (const VkSemaphore*)DE_NULL,
1401 VK_CHECK(vk.beginCommandBuffer(*copyCmdBuffer, &cmdBufferBeginInfo));
1402 vk.cmdCopyImageToBuffer(*copyCmdBuffer, colorImages[outLocation + locNdx].get()->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params);
1403 VK_CHECK(vk.endCommandBuffer(*copyCmdBuffer));
1405 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1406 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1407 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
1410 const VkMappedMemoryRange range =
1412 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
1413 DE_NULL, // const void* pNext;
1414 readImageBufferMemory->getMemory(), // VkDeviceMemory mem;
1415 0, // VkDeviceSize offset;
1416 imageSizeBytes, // VkDeviceSize size;
1419 VK_CHECK(vk.invalidateMappedMemoryRanges(vkDevice, 1u, &range));
1421 tmpBuf.setStorage(readFormat, renderSize.x(), renderSize.y());
1423 const tcu::TextureFormat resultFormat(tcu::TextureFormat::RGBA, format.type);
1424 const tcu::ConstPixelBufferAccess resultAccess(resultFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr());
1426 tcu::copy(tmpBuf.getAccess(), resultAccess);
1428 if (outSize == 4 && outNumLocs == 1)
1429 deMemcpy(dstPtrBase, tmpBuf.getAccess().getDataPtr(), numValues * outVecSize * sizeof(deUint32));
1432 for (int valNdx = 0; valNdx < numValues; valNdx++)
1434 const deUint32* srcPtr = (const deUint32*)tmpBuf.getAccess().getDataPtr() + valNdx * 4;
1435 deUint32* dstPtr = &dstPtrBase[outSize * valNdx + outVecSize * locNdx];
1436 deMemcpy(dstPtr, srcPtr, outVecSize * sizeof(deUint32));
1444 // VertexShaderExecutor
1446 class VertexShaderExecutor : public FragmentOutExecutor
1449 VertexShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1450 virtual ~VertexShaderExecutor (void);
1452 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst;}
1454 virtual void setShaderSources (SourceCollections& programCollection) const;
1458 VertexShaderExecutor::VertexShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1459 : FragmentOutExecutor (shaderSpec, shaderType)
1463 VertexShaderExecutor::~VertexShaderExecutor (void)
1467 void VertexShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1469 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShader(m_shaderSpec, "a_", "vtx_out_"));
1470 /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1471 programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(m_shaderSpec, false, m_outputLayout.locationMap, "vtx_out_", "o_"));
1474 // GeometryShaderExecutor
1476 class GeometryShaderExecutor : public FragmentOutExecutor
1479 GeometryShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1480 virtual ~GeometryShaderExecutor (void);
1482 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst; }
1484 virtual void setShaderSources (SourceCollections& programCollection) const;
1488 GeometryShaderExecutor::GeometryShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1489 : FragmentOutExecutor (shaderSpec, shaderType)
1493 GeometryShaderExecutor::~GeometryShaderExecutor (void)
1497 void GeometryShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1499 programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(m_shaderSpec.inputs, "a_", "vtx_out_"));
1501 programCollection.glslSources.add("geom") << glu::GeometrySource(generateGeometryShader(m_shaderSpec, "vtx_out_", "geom_out_"));
1503 /* \todo [2015-09-18 rsipka] set useIntOutputs parameter if needed. */
1504 programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(m_shaderSpec, false, m_outputLayout.locationMap, "geom_out_", "o_"));
1508 // FragmentShaderExecutor
1510 class FragmentShaderExecutor : public FragmentOutExecutor
1513 FragmentShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1514 virtual ~FragmentShaderExecutor (void);
1516 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst; }
1518 virtual void setShaderSources (SourceCollections& programCollection) const;
1522 FragmentShaderExecutor::FragmentShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1523 : FragmentOutExecutor (shaderSpec, shaderType)
1527 FragmentShaderExecutor::~FragmentShaderExecutor (void)
1531 void FragmentShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1533 programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(m_shaderSpec.inputs, "a_", "vtx_out_"));
1534 /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1535 programCollection.glslSources.add("frag") << glu::FragmentSource(generateFragmentShader(m_shaderSpec, false, m_outputLayout.locationMap, "vtx_out_", "o_"));
1538 // Shared utilities for compute and tess executors
1540 static deUint32 getVecStd430ByteAlignment (glu::DataType type)
1542 switch (glu::getDataTypeScalarSize(type))
1554 class BufferIoExecutor : public ShaderExecutor
1557 BufferIoExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1558 virtual ~BufferIoExecutor (void);
1560 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst; }
1565 INPUT_BUFFER_BINDING = 0,
1566 OUTPUT_BUFFER_BINDING = 1,
1569 void initBuffers (const Context& ctx, int numValues);
1570 VkBuffer getInputBuffer (void) const { return *m_inputBuffer; }
1571 VkBuffer getOutputBuffer (void) const { return *m_outputBuffer; }
1572 deUint32 getInputStride (void) const { return getLayoutStride(m_inputLayout); }
1573 deUint32 getOutputStride (void) const { return getLayoutStride(m_outputLayout); }
1575 void uploadInputBuffer (const Context& ctx, const void* const* inputPtrs, int numValues);
1576 void readOutputBuffer (const Context& ctx, void* const* outputPtrs, int numValues);
1578 static void declareBufferBlocks (std::ostream& src, const ShaderSpec& spec);
1579 static void generateExecBufferIo(std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName);
1582 Move<VkBuffer> m_inputBuffer;
1583 Move<VkBuffer> m_outputBuffer;
1590 deUint32 matrixStride;
1592 VarLayout (void) : offset(0), stride(0), matrixStride(0) {}
1595 static void computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout);
1596 static deUint32 getLayoutStride (const vector<VarLayout>& layout);
1598 static void copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1599 static void copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1601 de::MovePtr<Allocation> m_inputAlloc;
1602 de::MovePtr<Allocation> m_outputAlloc;
1604 vector<VarLayout> m_inputLayout;
1605 vector<VarLayout> m_outputLayout;
1608 BufferIoExecutor::BufferIoExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1609 : ShaderExecutor (shaderSpec, shaderType)
1611 computeVarLayout(m_shaderSpec.inputs, &m_inputLayout);
1612 computeVarLayout(m_shaderSpec.outputs, &m_outputLayout);
1615 BufferIoExecutor::~BufferIoExecutor (void)
1619 inline deUint32 BufferIoExecutor::getLayoutStride (const vector<VarLayout>& layout)
1621 return layout.empty() ? 0 : layout[0].stride;
1624 void BufferIoExecutor::computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout)
1626 deUint32 maxAlignment = 0;
1627 deUint32 curOffset = 0;
1629 DE_ASSERT(layout != DE_NULL);
1630 DE_ASSERT(layout->empty());
1631 layout->resize(symbols.size());
1633 for (size_t varNdx = 0; varNdx < symbols.size(); varNdx++)
1635 const Symbol& symbol = symbols[varNdx];
1636 const glu::DataType basicType = symbol.varType.getBasicType();
1637 VarLayout& layoutEntry = (*layout)[varNdx];
1639 if (glu::isDataTypeScalarOrVector(basicType))
1641 const deUint32 alignment = getVecStd430ByteAlignment(basicType);
1642 const deUint32 size = (deUint32)glu::getDataTypeScalarSize(basicType) * (int)sizeof(deUint32);
1644 curOffset = (deUint32)deAlign32((int)curOffset, (int)alignment);
1645 maxAlignment = de::max(maxAlignment, alignment);
1647 layoutEntry.offset = curOffset;
1648 layoutEntry.matrixStride = 0;
1652 else if (glu::isDataTypeMatrix(basicType))
1654 const int numVecs = glu::getDataTypeMatrixNumColumns(basicType);
1655 const glu::DataType vecType = glu::getDataTypeFloatVec(glu::getDataTypeMatrixNumRows(basicType));
1656 const deUint32 vecAlignment = getVecStd430ByteAlignment(vecType);
1658 curOffset = (deUint32)deAlign32((int)curOffset, (int)vecAlignment);
1659 maxAlignment = de::max(maxAlignment, vecAlignment);
1661 layoutEntry.offset = curOffset;
1662 layoutEntry.matrixStride = vecAlignment;
1664 curOffset += vecAlignment*numVecs;
1671 const deUint32 totalSize = (deUint32)deAlign32(curOffset, maxAlignment);
1673 for (vector<VarLayout>::iterator varIter = layout->begin(); varIter != layout->end(); ++varIter)
1674 varIter->stride = totalSize;
1678 void BufferIoExecutor::declareBufferBlocks (std::ostream& src, const ShaderSpec& spec)
1681 if (!spec.inputs.empty())
1683 glu::StructType inputStruct("Inputs");
1684 for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1685 inputStruct.addMember(symIter->name.c_str(), symIter->varType);
1686 src << glu::declare(&inputStruct) << ";\n";
1691 glu::StructType outputStruct("Outputs");
1692 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1693 outputStruct.addMember(symIter->name.c_str(), symIter->varType);
1694 src << glu::declare(&outputStruct) << ";\n";
1699 if (!spec.inputs.empty())
1701 src << "layout(set = 0, binding = " << int(INPUT_BUFFER_BINDING) << ", std430) buffer InBuffer\n"
1703 << " Inputs inputs[];\n"
1707 src << "layout(set = 0, binding = " << int(OUTPUT_BUFFER_BINDING) << ", std430) buffer OutBuffer\n"
1709 << " Outputs outputs[];\n"
1714 void BufferIoExecutor::generateExecBufferIo (std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName)
1716 for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1717 src << "\t" << glu::declare(symIter->varType, symIter->name) << " = inputs[" << invocationNdxName << "]." << symIter->name << ";\n";
1719 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1720 src << "\t" << glu::declare(symIter->varType, symIter->name) << ";\n";
1725 std::istringstream opSrc (spec.source);
1728 while (std::getline(opSrc, line))
1729 src << "\t" << line << "\n";
1733 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1734 src << "\toutputs[" << invocationNdxName << "]." << symIter->name << " = " << symIter->name << ";\n";
1737 void BufferIoExecutor::copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1739 if (varType.isBasicType())
1741 const glu::DataType basicType = varType.getBasicType();
1742 const bool isMatrix = glu::isDataTypeMatrix(basicType);
1743 const int scalarSize = glu::getDataTypeScalarSize(basicType);
1744 const int numVecs = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1745 const int numComps = scalarSize / numVecs;
1747 for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1749 for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1751 const int srcOffset = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1752 const int dstOffset = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1753 const deUint8* srcPtr = (const deUint8*)srcBasePtr + srcOffset;
1754 deUint8* dstPtr = (deUint8*)dstBasePtr + dstOffset;
1756 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1761 throw tcu::InternalError("Unsupported type");
1764 void BufferIoExecutor::copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1766 if (varType.isBasicType())
1768 const glu::DataType basicType = varType.getBasicType();
1769 const bool isMatrix = glu::isDataTypeMatrix(basicType);
1770 const int scalarSize = glu::getDataTypeScalarSize(basicType);
1771 const int numVecs = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1772 const int numComps = scalarSize / numVecs;
1774 for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1776 for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1778 const int srcOffset = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1779 const int dstOffset = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1780 const deUint8* srcPtr = (const deUint8*)srcBasePtr + srcOffset;
1781 deUint8* dstPtr = (deUint8*)dstBasePtr + dstOffset;
1783 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1788 throw tcu::InternalError("Unsupported type");
1791 void BufferIoExecutor::uploadInputBuffer (const Context& ctx, const void* const* inputPtrs, int numValues)
1793 const VkDevice vkDevice = ctx.getDevice();
1794 const DeviceInterface& vk = ctx.getDeviceInterface();
1796 const deUint32 inputStride = getLayoutStride(m_inputLayout);
1797 const int inputBufferSize = inputStride * numValues;
1799 if (inputBufferSize == 0)
1800 return; // No inputs
1802 DE_ASSERT(m_shaderSpec.inputs.size() == m_inputLayout.size());
1803 for (size_t inputNdx = 0; inputNdx < m_shaderSpec.inputs.size(); ++inputNdx)
1805 const glu::VarType& varType = m_shaderSpec.inputs[inputNdx].varType;
1806 const VarLayout& layout = m_inputLayout[inputNdx];
1808 copyToBuffer(varType, layout, numValues, inputPtrs[inputNdx], m_inputAlloc->getHostPtr());
1811 flushMappedMemoryRange(vk, vkDevice, m_inputAlloc->getMemory(), m_inputAlloc->getOffset(), inputBufferSize);
1814 void BufferIoExecutor::readOutputBuffer (const Context& ctx, void* const* outputPtrs, int numValues)
1816 const VkDevice vkDevice = ctx.getDevice();
1817 const DeviceInterface& vk = ctx.getDeviceInterface();
1819 const deUint32 outputStride = getLayoutStride(m_outputLayout);
1820 const int outputBufferSize = numValues * outputStride;
1822 DE_ASSERT(outputBufferSize > 0); // At least some outputs are required.
1824 invalidateMappedMemoryRange(vk, vkDevice, m_outputAlloc->getMemory(), m_outputAlloc->getOffset(), outputBufferSize);
1826 DE_ASSERT(m_shaderSpec.outputs.size() == m_outputLayout.size());
1827 for (size_t outputNdx = 0; outputNdx < m_shaderSpec.outputs.size(); ++outputNdx)
1829 const glu::VarType& varType = m_shaderSpec.outputs[outputNdx].varType;
1830 const VarLayout& layout = m_outputLayout[outputNdx];
1832 copyFromBuffer(varType, layout, numValues, m_outputAlloc->getHostPtr(), outputPtrs[outputNdx]);
1836 void BufferIoExecutor::initBuffers (const Context& ctx, int numValues)
1838 const deUint32 inputStride = getLayoutStride(m_inputLayout);
1839 const deUint32 outputStride = getLayoutStride(m_outputLayout);
1840 // Avoid creating zero-sized buffer/memory
1841 const size_t inputBufferSize = numValues * inputStride ? (numValues * inputStride) : 1;
1842 const size_t outputBufferSize = numValues * outputStride;
1844 // Upload data to buffer
1845 const VkDevice vkDevice = ctx.getDevice();
1846 const DeviceInterface& vk = ctx.getDeviceInterface();
1847 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex();
1848 Allocator& memAlloc = ctx.getDefaultAllocator();
1850 const VkBufferCreateInfo inputBufferParams =
1852 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1853 DE_NULL, // const void* pNext;
1854 0u, // VkBufferCreateFlags flags;
1855 inputBufferSize, // VkDeviceSize size;
1856 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
1857 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1858 1u, // deUint32 queueFamilyCount;
1859 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1862 m_inputBuffer = createBuffer(vk, vkDevice, &inputBufferParams);
1863 m_inputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_inputBuffer), MemoryRequirement::HostVisible);
1865 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_inputBuffer, m_inputAlloc->getMemory(), m_inputAlloc->getOffset()));
1867 const VkBufferCreateInfo outputBufferParams =
1869 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1870 DE_NULL, // const void* pNext;
1871 0u, // VkBufferCreateFlags flags;
1872 outputBufferSize, // VkDeviceSize size;
1873 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
1874 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1875 1u, // deUint32 queueFamilyCount;
1876 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1879 m_outputBuffer = createBuffer(vk, vkDevice, &outputBufferParams);
1880 m_outputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_outputBuffer), MemoryRequirement::HostVisible);
1882 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_outputBuffer, m_outputAlloc->getMemory(), m_outputAlloc->getOffset()));
1885 // ComputeShaderExecutor
1887 class ComputeShaderExecutor : public BufferIoExecutor
1890 ComputeShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1891 virtual ~ComputeShaderExecutor (void);
1893 virtual void setShaderSources (SourceCollections& programCollection) const;
1895 virtual void execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs);
1898 static std::string generateComputeShader (const ShaderSpec& spec);
1901 ComputeShaderExecutor::ComputeShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1902 : BufferIoExecutor (shaderSpec, shaderType)
1906 ComputeShaderExecutor::~ComputeShaderExecutor (void)
1910 std::string ComputeShaderExecutor::generateComputeShader (const ShaderSpec& spec)
1912 std::ostringstream src;
1913 src << "#version 310 es\n";
1915 if (!spec.globalDeclarations.empty())
1916 src << spec.globalDeclarations << "\n";
1918 src << "layout(local_size_x = 1) in;\n"
1921 declareBufferBlocks(src, spec);
1923 src << "void main (void)\n"
1925 << " uint invocationNdx = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z\n"
1926 << " + gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n";
1928 generateExecBufferIo(src, spec, "invocationNdx");
1935 void ComputeShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1937 programCollection.glslSources.add("compute") << glu::ComputeSource(generateComputeShader(m_shaderSpec));
1940 void ComputeShaderExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs)
1942 checkSupported(ctx, m_shaderType);
1944 const VkDevice vkDevice = ctx.getDevice();
1945 const DeviceInterface& vk = ctx.getDeviceInterface();
1946 const VkQueue queue = ctx.getUniversalQueue();
1947 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex();
1948 Allocator& memAlloc = ctx.getDefaultAllocator();
1950 Move<VkShaderModule> computeShaderModule;
1951 Move<VkPipeline> computePipeline;
1952 Move<VkPipelineLayout> pipelineLayout;
1953 Move<VkCommandPool> cmdPool;
1954 Move<VkDescriptorPool> descriptorPool;
1955 Move<VkDescriptorSetLayout> descriptorSetLayout;
1956 Move<VkDescriptorSet> descriptorSet;
1957 Move<VkFence> fence;
1959 initBuffers(ctx, numValues);
1961 // Setup input buffer & copy data
1962 uploadInputBuffer(ctx, inputs, numValues);
1964 // Create command pool
1966 const VkCommandPoolCreateInfo cmdPoolParams =
1968 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
1969 DE_NULL, // const void* pNext;
1970 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
1971 queueFamilyIndex // deUint32 queueFamilyIndex;
1974 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1977 // Create command buffer
1978 const VkCommandBufferAllocateInfo cmdBufferParams =
1980 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1981 DE_NULL, // const void* pNext;
1982 *cmdPool, // VkCmdPool cmdPool;
1983 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1984 1u // deUint32 bufferCount;
1987 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1989 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1990 DE_NULL, // const void* pNext;
1991 0u, // VkCmdBufferOptimizeFlags flags;
1992 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1995 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1996 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1997 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1998 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2000 addUniforms(vkDevice, vk, queue, queueFamilyIndex, memAlloc);
2002 descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
2003 descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2005 const VkDescriptorSetAllocateInfo allocInfo =
2007 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2011 &*descriptorSetLayout
2014 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2016 // Create pipeline layout
2018 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2020 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
2021 DE_NULL, // const void* pNext;
2022 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
2023 1u, // deUint32 CdescriptorSetCount;
2024 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
2025 0u, // deUint32 pushConstantRangeCount;
2026 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
2029 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2034 computeShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("compute"), 0);
2039 const VkPipelineShaderStageCreateInfo shaderStageParams[1] =
2042 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2043 DE_NULL, // const void* pNext;
2044 (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
2045 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagsBit stage;
2046 *computeShaderModule, // VkShaderModule shader;
2047 "main", // const char* pName;
2048 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2052 const VkComputePipelineCreateInfo computePipelineParams =
2054 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
2055 DE_NULL, // const void* pNext;
2056 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
2057 *shaderStageParams, // VkPipelineShaderStageCreateInfo cs;
2058 *pipelineLayout, // VkPipelineLayout layout;
2059 0u, // VkPipeline basePipelineHandle;
2060 0u, // int32_t basePipelineIndex;
2063 computePipeline = createComputePipeline(vk, vkDevice, DE_NULL, &computePipelineParams);
2068 const VkFenceCreateInfo fenceParams =
2070 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
2071 DE_NULL, // const void* pNext;
2072 0u // VkFenceCreateFlags flags;
2074 fence = createFence(vk, vkDevice, &fenceParams);
2077 const int maxValuesPerInvocation = ctx.getDeviceProperties().limits.maxComputeWorkGroupSize[0];
2079 const deUint32 inputStride = getInputStride();
2080 const deUint32 outputStride = getOutputStride();
2082 while (curOffset < numValues)
2084 Move<VkCommandBuffer> cmdBuffer;
2085 const int numToExec = de::min(maxValuesPerInvocation, numValues-curOffset);
2087 // Update descriptors
2089 DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2091 const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2093 *m_outputBuffer, // VkBuffer buffer;
2094 curOffset * outputStride, // VkDeviceSize offset;
2095 numToExec * outputStride // VkDeviceSize range;
2098 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2102 const VkDescriptorBufferInfo inputDescriptorBufferInfo =
2104 *m_inputBuffer, // VkBuffer buffer;
2105 curOffset * inputStride, // VkDeviceSize offset;
2106 numToExec * inputStride // VkDeviceSize range;
2109 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2112 uploadUniforms(descriptorSetUpdateBuilder, *descriptorSet);
2114 descriptorSetUpdateBuilder.update(vk, vkDevice);
2117 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
2118 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2119 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
2121 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
2123 vk.cmdDispatch(*cmdBuffer, numToExec, 1, 1);
2125 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2127 curOffset += numToExec;
2131 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2133 const VkSubmitInfo submitInfo =
2135 VK_STRUCTURE_TYPE_SUBMIT_INFO,
2138 (const VkSemaphore*)DE_NULL,
2139 (const VkPipelineStageFlags*)DE_NULL,
2143 (const VkSemaphore*)DE_NULL,
2146 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2147 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2152 readOutputBuffer(ctx, outputs, numValues);
2155 // Tessellation utils
2157 static std::string generateVertexShaderForTess (void)
2159 std::ostringstream src;
2160 src << "#version 310 es\n"
2161 << "void main (void)\n{\n"
2162 << " gl_Position = vec4(gl_VertexIndex/2, gl_VertexIndex%2, 0.0, 1.0);\n"
2168 class TessellationExecutor : public BufferIoExecutor
2171 TessellationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
2172 virtual ~TessellationExecutor (void);
2174 void renderTess (const Context& ctx, deUint32 numValues, deUint32 vertexCount, deUint32 patchControlPoints);
2177 TessellationExecutor::TessellationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2178 : BufferIoExecutor (shaderSpec, shaderType)
2182 TessellationExecutor::~TessellationExecutor (void)
2186 void TessellationExecutor::renderTess (const Context& ctx, deUint32 numValues, deUint32 vertexCount, deUint32 patchControlPoints)
2188 const size_t inputBufferSize = numValues * getInputStride();
2189 const VkDevice vkDevice = ctx.getDevice();
2190 const DeviceInterface& vk = ctx.getDeviceInterface();
2191 const VkQueue queue = ctx.getUniversalQueue();
2192 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex();
2193 Allocator& memAlloc = ctx.getDefaultAllocator();
2195 const tcu::UVec2 renderSize (DEFAULT_RENDER_WIDTH, DEFAULT_RENDER_HEIGHT);
2197 Move<VkImage> colorImage;
2198 de::MovePtr<Allocation> colorImageAlloc;
2199 VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
2200 Move<VkImageView> colorImageView;
2202 Move<VkRenderPass> renderPass;
2203 Move<VkFramebuffer> framebuffer;
2204 Move<VkPipelineLayout> pipelineLayout;
2205 Move<VkPipeline> graphicsPipeline;
2207 Move<VkShaderModule> vertexShaderModule;
2208 Move<VkShaderModule> tessControlShaderModule;
2209 Move<VkShaderModule> tessEvalShaderModule;
2210 Move<VkShaderModule> fragmentShaderModule;
2212 Move<VkCommandPool> cmdPool;
2213 Move<VkCommandBuffer> cmdBuffer;
2215 Move<VkFence> fence;
2217 Move<VkDescriptorPool> descriptorPool;
2218 Move<VkDescriptorSetLayout> descriptorSetLayout;
2219 Move<VkDescriptorSet> descriptorSet;
2221 // Create color image
2223 const VkImageCreateInfo colorImageParams =
2225 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2226 DE_NULL, // const void* pNext;
2227 0u, // VkImageCreateFlags flags;
2228 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2229 colorFormat, // VkFormat format;
2230 { renderSize.x(), renderSize.y(), 1u }, // VkExtent3D extent;
2231 1u, // deUint32 mipLevels;
2232 1u, // deUint32 arraySize;
2233 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2234 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2235 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
2236 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2237 1u, // deUint32 queueFamilyCount;
2238 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2239 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
2242 colorImage = createImage(vk, vkDevice, &colorImageParams);
2244 // Allocate and bind color image memory
2245 colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *colorImage), MemoryRequirement::Any);
2246 VK_CHECK(vk.bindImageMemory(vkDevice, *colorImage, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
2249 // Create color attachment view
2251 const VkImageViewCreateInfo colorImageViewParams =
2253 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2254 DE_NULL, // const void* pNext;
2255 0u, // VkImageViewCreateFlags flags;
2256 *colorImage, // VkImage image;
2257 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2258 colorFormat, // VkFormat format;
2260 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
2261 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
2262 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
2263 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
2264 }, // VkComponentsMapping components;
2266 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2267 0u, // deUint32 baseMipLevel;
2268 1u, // deUint32 mipLevels;
2269 0u, // deUint32 baseArraylayer;
2270 1u // deUint32 layerCount;
2271 } // VkImageSubresourceRange subresourceRange;
2274 colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
2277 // Create render pass
2279 const VkAttachmentDescription colorAttachmentDescription =
2281 0u, // VkAttachmentDescriptorFlags flags;
2282 colorFormat, // VkFormat format;
2283 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2284 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
2285 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2286 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2287 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
2288 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2289 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
2292 const VkAttachmentDescription attachments[1] =
2294 colorAttachmentDescription
2297 const VkAttachmentReference colorAttachmentReference =
2299 0u, // deUint32 attachment;
2300 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
2303 const VkSubpassDescription subpassDescription =
2305 0u, // VkSubpassDescriptionFlags flags;
2306 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
2307 0u, // deUint32 inputCount;
2308 DE_NULL, // const VkAttachmentReference* pInputAttachments;
2309 1u, // deUint32 colorCount;
2310 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
2311 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
2312 DE_NULL, // VkAttachmentReference depthStencilAttachment;
2313 0u, // deUint32 preserveCount;
2314 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
2317 const VkRenderPassCreateInfo renderPassParams =
2319 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
2320 DE_NULL, // const void* pNext;
2321 0u, // VkRenderPassCreateFlags flags;
2322 1u, // deUint32 attachmentCount;
2323 attachments, // const VkAttachmentDescription* pAttachments;
2324 1u, // deUint32 subpassCount;
2325 &subpassDescription, // const VkSubpassDescription* pSubpasses;
2326 0u, // deUint32 dependencyCount;
2327 DE_NULL // const VkSubpassDependency* pDependencies;
2330 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
2333 // Create framebuffer
2335 const VkFramebufferCreateInfo framebufferParams =
2337 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
2338 DE_NULL, // const void* pNext;
2339 0u, // VkFramebufferCreateFlags flags;
2340 *renderPass, // VkRenderPass renderPass;
2341 1u, // deUint32 attachmentCount;
2342 &*colorImageView, // const VkAttachmentBindInfo* pAttachments;
2343 (deUint32)renderSize.x(), // deUint32 width;
2344 (deUint32)renderSize.y(), // deUint32 height;
2345 1u // deUint32 layers;
2348 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
2351 // Create descriptors
2353 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2354 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2355 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2356 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2358 addUniforms(vkDevice, vk, queue, queueFamilyIndex, memAlloc);
2360 descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
2361 descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2363 const VkDescriptorSetAllocateInfo allocInfo =
2365 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2369 &*descriptorSetLayout
2372 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2373 // Update descriptors
2375 DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2376 const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2378 *m_outputBuffer, // VkBuffer buffer;
2379 0u, // VkDeviceSize offset;
2380 VK_WHOLE_SIZE // VkDeviceSize range;
2383 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2385 VkDescriptorBufferInfo inputDescriptorBufferInfo =
2387 0, // VkBuffer buffer;
2388 0u, // VkDeviceSize offset;
2389 VK_WHOLE_SIZE // VkDeviceSize range;
2392 if (inputBufferSize > 0)
2394 inputDescriptorBufferInfo.buffer = *m_inputBuffer;
2396 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2399 uploadUniforms(descriptorSetUpdateBuilder, *descriptorSet);
2401 descriptorSetUpdateBuilder.update(vk, vkDevice);
2405 // Create pipeline layout
2407 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2409 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
2410 DE_NULL, // const void* pNext;
2411 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
2412 1u, // deUint32 descriptorSetCount;
2413 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
2414 0u, // deUint32 pushConstantRangeCount;
2415 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
2418 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2421 // Create shader modules
2423 vertexShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("vert"), 0);
2424 tessControlShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("tess_control"), 0);
2425 tessEvalShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("tess_eval"), 0);
2426 fragmentShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("frag"), 0);
2431 const VkPipelineShaderStageCreateInfo shaderStageParams[4] =
2434 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2435 DE_NULL, // const void* pNext;
2436 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2437 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBit stage;
2438 *vertexShaderModule, // VkShaderModule shader;
2439 "main", // const char* pName;
2440 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2443 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2444 DE_NULL, // const void* pNext;
2445 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2446 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, // VkShaderStageFlagBit stage;
2447 *tessControlShaderModule, // VkShaderModule shader;
2448 "main", // const char* pName;
2449 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2452 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2453 DE_NULL, // const void* pNext;
2454 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2455 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, // VkShaderStageFlagBit stage;
2456 *tessEvalShaderModule, // VkShaderModule shader;
2457 "main", // const char* pName;
2458 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2461 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2462 DE_NULL, // const void* pNext;
2463 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2464 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBit stage;
2465 *fragmentShaderModule, // VkShaderModule shader;
2466 "main", // const char* pName;
2467 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2471 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
2473 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
2474 DE_NULL, // const void* pNext;
2475 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
2476 0u, // deUint32 bindingCount;
2477 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
2478 0u, // deUint32 attributeCount;
2479 DE_NULL, // const VkVertexInputAttributeDescription* pvertexAttributeDescriptions;
2482 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
2484 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
2485 DE_NULL, // const void* pNext;
2486 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2487 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, // VkPrimitiveTopology topology;
2488 DE_FALSE // VkBool32 primitiveRestartEnable;
2491 struct VkPipelineTessellationStateCreateInfo tessellationStateParams =
2493 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
2494 DE_NULL, // const void* pNext;
2495 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags;
2496 patchControlPoints // uint32_t patchControlPoints;
2499 const VkViewport viewport =
2501 0.0f, // float originX;
2502 0.0f, // float originY;
2503 (float)renderSize.x(), // float width;
2504 (float)renderSize.y(), // float height;
2505 0.0f, // float minDepth;
2506 1.0f // float maxDepth;
2509 const VkRect2D scissor =
2514 }, // VkOffset2D offset;
2516 renderSize.x(), // deUint32 width;
2517 renderSize.y(), // deUint32 height;
2518 }, // VkExtent2D extent;
2521 const VkPipelineViewportStateCreateInfo viewportStateParams =
2523 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
2524 DE_NULL, // const void* pNext;
2525 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewPortStateCreateFlags flags;
2526 1u, // deUint32 viewportCount;
2527 &viewport, // const VkViewport* pViewports;
2528 1u, // deUint32 scissorsCount;
2529 &scissor // const VkRect2D* pScissors;
2532 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
2534 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
2535 DE_NULL, // const void* pNext;
2536 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStageCreateFlags flags;
2537 VK_FALSE, // VkBool32 depthClipEnable;
2538 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
2539 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
2540 VK_CULL_MODE_NONE, // VkCullMode cullMode;
2541 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
2542 VK_FALSE, // VkBool32 depthBiasEnable;
2543 0.0f, // float depthBias;
2544 0.0f, // float depthBiasClamp;
2545 0.0f, // float slopeScaledDepthBias;
2546 1.0f // float lineWidth;
2549 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
2551 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
2552 DE_NULL, // const void* pNext;
2553 0u, // VkPipelineMultisampleStateCreateFlags flags;
2554 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
2555 VK_FALSE, // VkBool32 sampleShadingEnable;
2556 0.0f, // float minSampleShading;
2557 DE_NULL, // const VkSampleMask* pSampleMask;
2558 VK_FALSE, // VkBool32 alphaToCoverageEnable;
2559 VK_FALSE // VkBool32 alphaToOneEnable;
2562 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
2564 VK_FALSE, // VkBool32 blendEnable;
2565 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcBlendColor;
2566 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destBlendColor;
2567 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
2568 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcBlendAlpha;
2569 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destBlendAlpha;
2570 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
2571 (VK_COLOR_COMPONENT_R_BIT |
2572 VK_COLOR_COMPONENT_G_BIT |
2573 VK_COLOR_COMPONENT_B_BIT |
2574 VK_COLOR_COMPONENT_A_BIT) // VkColorComponentFlags colorWriteMask;
2577 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
2579 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
2580 DE_NULL, // const void* pNext;
2581 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags
2582 VK_FALSE, // VkBool32 logicOpEnable;
2583 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
2584 1u, // deUint32 attachmentCount;
2585 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
2586 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConst[4];
2589 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
2591 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
2592 DE_NULL, // const void* pNext;
2593 0u, // VkPipelineCreateFlags flags;
2594 4u, // deUint32 stageCount;
2595 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages;
2596 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
2597 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
2598 &tessellationStateParams, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
2599 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
2600 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
2601 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
2602 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
2603 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
2604 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
2605 *pipelineLayout, // VkPipelineLayout layout;
2606 *renderPass, // VkRenderPass renderPass;
2607 0u, // deUint32 subpass;
2608 0u, // VkPipeline basePipelineHandle;
2609 0u // deInt32 basePipelineIndex;
2612 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
2615 // Create command pool
2617 const VkCommandPoolCreateInfo cmdPoolParams =
2619 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
2620 DE_NULL, // const void* pNext;
2621 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
2622 queueFamilyIndex, // deUint32 queueFamilyIndex;
2625 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
2628 // Create command buffer
2630 const VkCommandBufferAllocateInfo cmdBufferParams =
2632 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
2633 DE_NULL, // const void* pNext;
2634 *cmdPool, // VkCmdPool cmdPool;
2635 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
2636 1u // uint32_t bufferCount;
2639 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
2641 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
2642 DE_NULL, // const void* pNext;
2643 0u, // VkCmdBufferOptimizeFlags flags;
2644 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2647 const VkClearValue clearValues[1] =
2649 getDefaultClearColor()
2652 const VkRenderPassBeginInfo renderPassBeginInfo =
2654 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
2655 DE_NULL, // const void* pNext;
2656 *renderPass, // VkRenderPass renderPass;
2657 *framebuffer, // VkFramebuffer framebuffer;
2658 { { 0, 0 }, { renderSize.x(), renderSize.y() } }, // VkRect2D renderArea;
2659 1, // deUint32 attachmentCount;
2660 clearValues // const VkClearValue* pClearValues;
2663 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
2665 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2667 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2669 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
2671 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
2673 vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
2675 vk.cmdEndRenderPass(*cmdBuffer);
2676 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2681 const VkFenceCreateInfo fenceParams =
2683 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
2684 DE_NULL, // const void* pNext;
2685 0u // VkFenceCreateFlags flags;
2687 fence = createFence(vk, vkDevice, &fenceParams);
2692 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2693 const VkSubmitInfo submitInfo =
2695 VK_STRUCTURE_TYPE_SUBMIT_INFO,
2698 (const VkSemaphore*)0,
2699 (const VkPipelineStageFlags*)DE_NULL,
2703 (const VkSemaphore*)0,
2705 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2706 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2710 // TessControlExecutor
2712 class TessControlExecutor : public TessellationExecutor
2715 TessControlExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
2716 virtual ~TessControlExecutor (void);
2718 virtual void setShaderSources (SourceCollections& programCollection) const;
2720 virtual void execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs);
2723 static std::string generateTessControlShader (const ShaderSpec& shaderSpec);
2726 TessControlExecutor::TessControlExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2727 : TessellationExecutor (shaderSpec, shaderType)
2731 TessControlExecutor::~TessControlExecutor (void)
2735 std::string TessControlExecutor::generateTessControlShader (const ShaderSpec& shaderSpec)
2737 std::ostringstream src;
2738 src << "#version 310 es\n"
2739 "#extension GL_EXT_tessellation_shader : require\n\n";
2741 if (!shaderSpec.globalDeclarations.empty())
2742 src << shaderSpec.globalDeclarations << "\n";
2744 src << "\nlayout(vertices = 1) out;\n\n";
2746 declareBufferBlocks(src, shaderSpec);
2748 src << "void main (void)\n{\n";
2750 for (int ndx = 0; ndx < 2; ndx++)
2751 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2753 for (int ndx = 0; ndx < 4; ndx++)
2754 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2757 << "\thighp uint invocationId = uint(gl_PrimitiveID);\n";
2759 generateExecBufferIo(src, shaderSpec, "invocationId");
2766 static std::string generateEmptyTessEvalShader ()
2768 std::ostringstream src;
2770 src << "#version 310 es\n"
2771 "#extension GL_EXT_tessellation_shader : require\n\n";
2773 src << "layout(triangles, ccw) in;\n";
2775 src << "\nvoid main (void)\n{\n"
2776 << "\tgl_Position = vec4(gl_TessCoord.xy, 0.0, 1.0);\n"
2782 void TessControlExecutor::setShaderSources (SourceCollections& programCollection) const
2784 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess());
2785 programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generateTessControlShader(m_shaderSpec));
2786 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateEmptyTessEvalShader());
2787 programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource());
2790 void TessControlExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs)
2792 const deUint32 patchSize = 3;
2794 checkSupported(ctx, m_shaderType);
2796 initBuffers(ctx, numValues);
2798 // Setup input buffer & copy data
2799 uploadInputBuffer(ctx, inputs, numValues);
2801 renderTess(ctx, numValues, patchSize * numValues, patchSize);
2804 readOutputBuffer(ctx, outputs, numValues);
2807 // TessEvaluationExecutor
2809 class TessEvaluationExecutor : public TessellationExecutor
2812 TessEvaluationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
2813 virtual ~TessEvaluationExecutor (void);
2815 virtual void setShaderSources (SourceCollections& programCollection) const;
2817 virtual void execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs);
2820 static std::string generateTessEvalShader (const ShaderSpec& shaderSpec);
2823 TessEvaluationExecutor::TessEvaluationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2824 : TessellationExecutor (shaderSpec, shaderType)
2828 TessEvaluationExecutor::~TessEvaluationExecutor (void)
2832 static std::string generatePassthroughTessControlShader (void)
2834 std::ostringstream src;
2836 src << "#version 310 es\n"
2837 "#extension GL_EXT_tessellation_shader : require\n\n";
2839 src << "layout(vertices = 1) out;\n\n";
2841 src << "void main (void)\n{\n";
2843 for (int ndx = 0; ndx < 2; ndx++)
2844 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2846 for (int ndx = 0; ndx < 4; ndx++)
2847 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2854 std::string TessEvaluationExecutor::generateTessEvalShader (const ShaderSpec& shaderSpec)
2856 std::ostringstream src;
2858 src << "#version 310 es\n"
2859 "#extension GL_EXT_tessellation_shader : require\n\n";
2861 if (!shaderSpec.globalDeclarations.empty())
2862 src << shaderSpec.globalDeclarations << "\n";
2866 src << "layout(isolines, equal_spacing) in;\n\n";
2868 declareBufferBlocks(src, shaderSpec);
2870 src << "void main (void)\n{\n"
2871 << "\tgl_Position = vec4(gl_TessCoord.x, 0.0, 0.0, 1.0);\n"
2872 << "\thighp uint invocationId = uint(gl_PrimitiveID)*2u + (gl_TessCoord.x > 0.5 ? 1u : 0u);\n";
2874 generateExecBufferIo(src, shaderSpec, "invocationId");
2881 void TessEvaluationExecutor::setShaderSources (SourceCollections& programCollection) const
2883 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess());
2884 programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generatePassthroughTessControlShader());
2885 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateTessEvalShader(m_shaderSpec));
2886 programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource());
2889 void TessEvaluationExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs)
2891 checkSupported(ctx, m_shaderType);
2893 const int patchSize = 2;
2894 const int alignedValues = deAlign32(numValues, patchSize);
2896 // Initialize buffers with aligned value count to make room for padding
2897 initBuffers(ctx, alignedValues);
2899 // Setup input buffer & copy data
2900 uploadInputBuffer(ctx, inputs, numValues);
2902 renderTess(ctx, (deUint32)alignedValues, (deUint32)alignedValues, (deUint32)patchSize);
2905 readOutputBuffer(ctx, outputs, numValues);
2912 ShaderExecutor::ShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2913 : m_shaderSpec (shaderSpec)
2914 , m_shaderType (shaderType)
2918 ShaderExecutor::~ShaderExecutor (void)
2924 ShaderExecutor* createExecutor (glu::ShaderType shaderType, const ShaderSpec& shaderSpec)
2928 case glu::SHADERTYPE_VERTEX: return new VertexShaderExecutor (shaderSpec, shaderType);
2929 case glu::SHADERTYPE_TESSELLATION_CONTROL: return new TessControlExecutor (shaderSpec, shaderType);
2930 case glu::SHADERTYPE_TESSELLATION_EVALUATION: return new TessEvaluationExecutor (shaderSpec, shaderType);
2931 case glu::SHADERTYPE_GEOMETRY: return new GeometryShaderExecutor (shaderSpec, shaderType);
2932 case glu::SHADERTYPE_FRAGMENT: return new FragmentShaderExecutor (shaderSpec, shaderType);
2933 case glu::SHADERTYPE_COMPUTE: return new ComputeShaderExecutor (shaderSpec, shaderType);
2935 throw tcu::InternalError("Unsupported shader type");
2939 de::MovePtr<ShaderExecutor::BufferUniform> ShaderExecutor::createBufferUniform (const VkDevice& vkDevice,
2940 const DeviceInterface& vk,
2941 const VkQueue /*queue*/,
2942 const deUint32 queueFamilyIndex,
2943 Allocator& memAlloc,
2944 deUint32 bindingLocation,
2945 VkDescriptorType descriptorType,
2947 const void* dataPtr)
2949 DE_ASSERT(descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2951 VkImageUsageFlags usage = descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
2953 const VkBufferCreateInfo uniformBufferParams =
2955 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2956 DE_NULL, // const void* pNext;
2957 0u, // VkBufferCreateFlags flags;
2958 size, // VkDeviceSize size;
2959 usage, // VkBufferUsageFlags usage;
2960 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2961 1u, // deUint32 queueFamilyIndexCount;
2962 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
2965 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &uniformBufferParams);
2966 de::MovePtr<Allocation> alloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
2967 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
2969 deMemcpy(alloc->getHostPtr(), dataPtr, size);
2970 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), size);
2972 de::MovePtr<BufferUniform> uniformInfo(new BufferUniform());
2973 uniformInfo->type = descriptorType;
2974 uniformInfo->descriptor = makeDescriptorBufferInfo(*buffer, 0u, size);
2975 uniformInfo->location = bindingLocation;
2976 uniformInfo->buffer = VkBufferSp(new Unique<VkBuffer>(buffer));
2977 uniformInfo->alloc = AllocationSp(alloc.release());
2982 void ShaderExecutor::setupUniformData (const VkDevice& vkDevice,
2983 const DeviceInterface& vk,
2984 const VkQueue queue,
2985 const deUint32 queueFamilyIndex,
2986 Allocator& memAlloc,
2987 deUint32 bindingLocation,
2988 VkDescriptorType descriptorType,
2990 const void* dataPtr)
2992 de::MovePtr<BufferUniform> uniform = createBufferUniform(vkDevice, vk, queue, queueFamilyIndex, memAlloc, bindingLocation, descriptorType, size, dataPtr);
2994 m_descriptorSetLayoutBuilder.addSingleBinding(descriptorType, VK_SHADER_STAGE_ALL);
2995 m_descriptorPoolBuilder.addType(descriptorType);
2997 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform)));
3000 void ShaderExecutor::setupUniformArray (const VkDevice& vkDevice,
3001 const DeviceInterface& vk,
3002 const VkQueue queue,
3003 const deUint32 queueFamilyIndex,
3004 Allocator& memAlloc,
3005 deUint32 bindingLocation,
3006 VkDescriptorType descriptorType,
3009 const void* dataPtr)
3011 DE_ASSERT(arraySize > 0);
3013 de::MovePtr<BufferArrayUniform> bufferArray (new BufferArrayUniform());
3015 bufferArray->type = descriptorType;
3016 bufferArray->location = bindingLocation;
3018 for (deUint32 ndx = 0; ndx < arraySize; ++ndx)
3020 const void* bufferData = ((deUint8*)dataPtr) + (ndx * size);
3021 de::MovePtr<BufferUniform> uniform = createBufferUniform(vkDevice, vk, queue, queueFamilyIndex, memAlloc, bindingLocation, descriptorType, size, bufferData);
3023 bufferArray->uniforms.push_back(BufferUniformSp(new de::UniquePtr<BufferUniform>(uniform)));
3026 m_descriptorSetLayoutBuilder.addArrayBinding(descriptorType, arraySize, VK_SHADER_STAGE_ALL);
3027 m_descriptorPoolBuilder.addType(descriptorType, arraySize);
3029 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(bufferArray)));
3032 void ShaderExecutor::setupSamplerData (const VkDevice& vkDevice,
3033 const DeviceInterface& vk,
3034 const VkQueue queue,
3035 const deUint32 queueFamilyIndex,
3036 Allocator& memAlloc,
3037 deUint32 bindingLocation,
3038 deUint32 numSamplers,
3039 const tcu::Sampler& refSampler,
3040 const tcu::TextureFormat& texFormat,
3041 const tcu::IVec3& texSize,
3042 VkImageType imageType,
3043 VkImageViewType imageViewType,
3046 DE_ASSERT(numSamplers > 0);
3048 de::MovePtr<SamplerArrayUniform> samplers (new SamplerArrayUniform());
3050 samplers->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
3051 samplers->location = bindingLocation;
3053 for (deUint32 ndx = 0; ndx < numSamplers; ++ndx)
3055 const int offset = ndx * texSize.x() * texSize.y() * texSize.z() * texFormat.getPixelSize();
3056 const void* samplerData = ((deUint8*)data) + offset;
3057 de::MovePtr<SamplerUniform> uniform = createSamplerUniform(vkDevice, vk, queue, queueFamilyIndex, memAlloc, bindingLocation, refSampler, texFormat, texSize, imageType, imageViewType, samplerData);
3059 samplers->uniforms.push_back(SamplerUniformSp(new de::UniquePtr<SamplerUniform>(uniform)));
3062 m_descriptorSetLayoutBuilder.addArraySamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, numSamplers, VK_SHADER_STAGE_ALL, DE_NULL);
3063 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, numSamplers);
3065 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(samplers)));
3068 void ShaderExecutor::addSamplerUniform (deUint32 bindingLocation,
3069 VkImageView imageView,
3072 de::MovePtr<UnmanagedSamplerUniform> samplerUniform(new UnmanagedSamplerUniform());
3074 const VkDescriptorImageInfo descriptor =
3078 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
3081 samplerUniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
3082 samplerUniform->location = bindingLocation;
3083 samplerUniform->descriptor = descriptor;
3085 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(samplerUniform)));
3087 m_descriptorSetLayoutBuilder.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_ALL, DE_NULL);
3088 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1);
3091 const void* ShaderExecutor::getBufferPtr (const deUint32 bindingLocation) const
3093 std::vector<UniformInfoSp>::const_iterator it = m_uniformInfos.begin();
3094 for (; it != m_uniformInfos.end(); it++)
3096 const UniformInfo* uniformInfo = it->get()->get();
3097 if (uniformInfo->getType() == UniformInfo::UNIFORM_TYPE_BUFFER && uniformInfo->location == bindingLocation)
3099 const BufferUniform* bufferUniform = static_cast<const BufferUniform*>(uniformInfo);
3100 return bufferUniform->alloc->getHostPtr();
3107 void ShaderExecutor::addUniforms (const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc)
3109 if (!m_uniformSetup)
3112 for (std::vector<UniformDataSp>::const_iterator it = m_uniformSetup->uniforms().begin(); it != m_uniformSetup->uniforms().end(); ++it)
3114 const UniformDataBase* uniformData = it->get()->get();
3115 uniformData->setup(*this, vkDevice, vk, queue, queueFamilyIndex, memAlloc);
3119 void ShaderExecutor::uploadUniforms (DescriptorSetUpdateBuilder& descriptorSetUpdateBuilder, VkDescriptorSet descriptorSet)
3121 for (std::vector<UniformInfoSp>::const_iterator it = m_uniformInfos.begin(); it != m_uniformInfos.end(); ++it)
3123 const UniformInfo* uniformInfo = it->get()->get();
3124 UniformInfo::UniformType uniformType = uniformInfo->getType();
3126 if (uniformType == UniformInfo::UNIFORM_TYPE_BUFFER_ARRAY)
3128 const BufferArrayUniform* arrayInfo = static_cast<const BufferArrayUniform*>(uniformInfo);
3129 std::vector<VkDescriptorBufferInfo> descriptors;
3131 for (std::vector<BufferUniformSp>::const_iterator ait = arrayInfo->uniforms.begin(); ait != arrayInfo->uniforms.end(); ++ait)
3133 descriptors.push_back(ait->get()->get()->descriptor);
3136 descriptorSetUpdateBuilder.writeArray(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(uniformInfo->location), uniformInfo->type, (deUint32)descriptors.size(), &descriptors[0]);
3138 else if (uniformType == UniformInfo::UNIFORM_TYPE_SAMPLER_ARRAY)
3140 const SamplerArrayUniform* arrayInfo = static_cast<const SamplerArrayUniform*>(uniformInfo);
3141 std::vector<VkDescriptorImageInfo> descriptors;
3143 for (std::vector<SamplerUniformSp>::const_iterator ait = arrayInfo->uniforms.begin(); ait != arrayInfo->uniforms.end(); ++ait)
3145 descriptors.push_back(ait->get()->get()->descriptor);
3148 descriptorSetUpdateBuilder.writeArray(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(uniformInfo->location), uniformInfo->type, (deUint32)descriptors.size(), &descriptors[0]);
3150 else if (uniformType == UniformInfo::UNIFORM_TYPE_BUFFER)
3152 const BufferUniform* bufferUniform = static_cast<const BufferUniform*>(uniformInfo);
3153 descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(bufferUniform->location), bufferUniform->type, &bufferUniform->descriptor);
3155 else if (uniformType == UniformInfo::UNIFORM_TYPE_SAMPLER)
3157 const SamplerUniform* samplerUniform = static_cast<const SamplerUniform*>(uniformInfo);
3158 descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(samplerUniform->location), samplerUniform->type, &samplerUniform->descriptor);
3160 else if (uniformType == UniformInfo::UNIFORM_TYPE_UNMANAGED_SAMPLER)
3162 const UnmanagedSamplerUniform* samplerUniform = static_cast<const UnmanagedSamplerUniform*>(uniformInfo);
3163 descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(samplerUniform->location), samplerUniform->type, &samplerUniform->descriptor);
3168 void ShaderExecutor::uploadImage (const VkDevice& vkDevice,
3169 const DeviceInterface& vk,
3170 const VkQueue queue,
3171 const deUint32 queueFamilyIndex,
3172 Allocator& memAlloc,
3173 const tcu::TextureFormat& texFormat,
3174 const tcu::IVec3& texSize,
3176 const deUint32 arraySize,
3177 const VkImageAspectFlags aspectMask,
3180 const deUint32 unalignedTextureSize = texSize.x() * texSize.y() * texSize.z() * texFormat.getPixelSize();
3181 const deUint32 alignedTextureSize = deAlign32(unalignedTextureSize, 4u);
3182 deUint32 bufferSize;
3183 Move<VkBuffer> buffer;
3184 de::MovePtr<Allocation> bufferAlloc;
3185 Move<VkCommandPool> cmdPool;
3186 Move<VkCommandBuffer> cmdBuffer;
3187 Move<VkFence> fence;
3188 std::vector<deUint32> levelDataSizes;
3190 // Calculate buffer size
3191 bufferSize = arraySize * alignedTextureSize;
3193 // Create source buffer
3195 const VkBufferCreateInfo bufferParams =
3197 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
3198 DE_NULL, // const void* pNext;
3199 0u, // VkBufferCreateFlags flags;
3200 bufferSize, // VkDeviceSize size;
3201 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
3202 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3203 0u, // deUint32 queueFamilyIndexCount;
3204 DE_NULL, // const deUint32* pQueueFamilyIndices;
3207 buffer = createBuffer(vk, vkDevice, &bufferParams);
3208 bufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
3209 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
3212 // Create command pool and buffer
3214 const VkCommandPoolCreateInfo cmdPoolParams =
3216 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
3217 DE_NULL, // const void* pNext;
3218 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags;
3219 queueFamilyIndex, // deUint32 queueFamilyIndex;
3222 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
3224 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
3226 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
3227 DE_NULL, // const void* pNext;
3228 *cmdPool, // VkCommandPool commandPool;
3229 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
3230 1u, // deUint32 bufferCount;
3233 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
3238 const VkFenceCreateInfo fenceParams =
3240 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
3241 DE_NULL, // const void* pNext;
3242 0u // VkFenceCreateFlags flags;
3245 fence = createFence(vk, vkDevice, &fenceParams);
3248 // Barriers for copying buffer to image
3249 const VkBufferMemoryBarrier preBufferBarrier =
3251 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
3252 DE_NULL, // const void* pNext;
3253 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
3254 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
3255 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
3256 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
3257 *buffer, // VkBuffer buffer;
3258 0u, // VkDeviceSize offset;
3259 bufferSize // VkDeviceSize size;
3262 const VkImageMemoryBarrier preImageBarrier =
3264 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3265 DE_NULL, // const void* pNext;
3266 0u, // VkAccessFlags srcAccessMask;
3267 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
3268 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
3269 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
3270 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
3271 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
3272 destImage, // VkImage image;
3273 { // VkImageSubresourceRange subresourceRange;
3274 aspectMask, // VkImageAspect aspect;
3275 0u, // deUint32 baseMipLevel;
3276 1u, // deUint32 mipLevels;
3277 0u, // deUint32 baseArraySlice;
3278 arraySize // deUint32 arraySize;
3282 const VkImageMemoryBarrier postImageBarrier =
3284 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3285 DE_NULL, // const void* pNext;
3286 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
3287 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
3288 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
3289 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout;
3290 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
3291 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
3292 destImage, // VkImage image;
3293 { // VkImageSubresourceRange subresourceRange;
3294 aspectMask, // VkImageAspect aspect;
3295 0u, // deUint32 baseMipLevel;
3296 1u, // deUint32 mipLevels;
3297 0u, // deUint32 baseArraySlice;
3298 arraySize // deUint32 arraySize;
3302 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
3304 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
3305 DE_NULL, // const void* pNext;
3306 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
3307 (const VkCommandBufferInheritanceInfo*)DE_NULL,
3310 std::vector<VkBufferImageCopy> copyRegions;
3313 deUint32 layerDataOffset = 0;
3315 for (deUint32 layerNdx = 0; layerNdx < arraySize; ++layerNdx)
3317 const VkBufferImageCopy layerRegion =
3319 layerDataOffset, // VkDeviceSize bufferOffset;
3320 (deUint32)texSize.x(), // deUint32 bufferRowLength;
3321 (deUint32)texSize.y(), // deUint32 bufferImageHeight;
3322 { // VkImageSubresourceLayers imageSubresource;
3328 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
3329 { // VkExtent3D imageExtent;
3330 (deUint32)texSize.x(),
3331 (deUint32)texSize.y(),
3332 (deUint32)texSize.z()
3336 copyRegions.push_back(layerRegion);
3337 layerDataOffset += alignedTextureSize;
3341 // Write buffer data
3343 deUint8* destPtr = (deUint8*)bufferAlloc->getHostPtr();
3344 deUint32 levelOffset = 0;
3346 for (deUint32 layerNdx = 0; layerNdx < arraySize; ++layerNdx)
3348 tcu::ConstPixelBufferAccess access (texFormat, texSize, data);
3349 tcu::PixelBufferAccess destAccess (texFormat, texSize, destPtr + levelOffset);
3351 tcu::copy(destAccess, access);
3352 levelOffset += alignedTextureSize;
3356 flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
3358 // Copy buffer to image
3359 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
3360 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
3361 vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data());
3362 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
3363 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
3365 const VkSubmitInfo submitInfo =
3367 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
3368 DE_NULL, // const void* pNext;
3369 0u, // deUint32 waitSemaphoreCount;
3370 DE_NULL, // const VkSemaphore* pWaitSemaphores;
3372 1u, // deUint32 commandBufferCount;
3373 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
3374 0u, // deUint32 signalSemaphoreCount;
3375 DE_NULL // const VkSemaphore* pSignalSemaphores;
3378 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
3379 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
3382 de::MovePtr<ShaderExecutor::SamplerUniform> ShaderExecutor::createSamplerUniform (const VkDevice& vkDevice,
3383 const DeviceInterface& vk,
3384 const VkQueue queue,
3385 const deUint32 queueFamilyIndex,
3386 Allocator& memAlloc,
3387 deUint32 bindingLocation,
3388 const tcu::Sampler& refSampler,
3389 const tcu::TextureFormat& texFormat,
3390 const tcu::IVec3& texSize,
3391 VkImageType imageType,
3392 VkImageViewType imageViewType,
3395 const VkFormat format = mapTextureFormat(texFormat);
3396 const bool isCube = imageViewType == VK_IMAGE_VIEW_TYPE_CUBE;
3397 const bool isShadowSampler = texFormat == tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
3398 const VkImageCreateFlags imageFlags = isCube ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlags)0;
3399 const deUint32 arraySize = isCube ? 6u : 1u;
3400 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
3401 VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3402 Move<VkImage> vkTexture;
3403 de::MovePtr<Allocation> allocation;
3405 if (isShadowSampler)
3406 imageUsage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
3409 const VkImageCreateInfo imageParams =
3411 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3412 DE_NULL, // const void* pNext;
3413 imageFlags, // VkImageCreateFlags flags;
3414 imageType, // VkImageType imageType;
3415 format, // VkFormat format;
3416 { // VkExtent3D extent;
3417 (deUint32)texSize.x(),
3418 (deUint32)texSize.y(),
3419 (deUint32)texSize.z()
3421 1u, // deUint32 mipLevels;
3422 arraySize, // deUint32 arrayLayers;
3423 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
3424 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
3425 imageUsage, // VkImageUsageFlags usage;
3426 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3427 1u, // deUint32 queueFamilyIndexCount;
3428 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
3429 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
3432 vkTexture = createImage(vk, vkDevice, &imageParams);
3433 allocation = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any);
3434 VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset()));
3436 // Upload texture data
3437 uploadImage(vkDevice, vk, queue, queueFamilyIndex, memAlloc, texFormat, texSize, data, arraySize, aspectMask, *vkTexture);
3440 const VkSamplerCreateInfo samplerParams = mapSampler(refSampler, texFormat);
3441 Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams);
3443 const VkImageViewCreateInfo viewParams =
3445 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
3446 NULL, // const voide* pNexŧ;
3447 0u, // VkImageViewCreateFlags flags;
3448 *vkTexture, // VkImage image;
3449 imageViewType, // VkImageViewType viewType;
3450 format, // VkFormat format;
3452 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
3453 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
3454 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
3455 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
3456 }, // VkComponentMapping components;
3458 aspectMask, // VkImageAspectFlags aspectMask;
3459 0, // deUint32 baseMipLevel;
3460 1, // deUint32 mipLevels;
3461 0, // deUint32 baseArraySlice;
3462 arraySize // deUint32 arraySize;
3463 } // VkImageSubresourceRange subresourceRange;
3466 Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams);
3468 const VkDescriptorImageInfo descriptor =
3470 sampler.get(), // VkSampler sampler;
3471 imageView.get(), // VkImageView imageView;
3472 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout imageLayout;
3475 de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
3476 uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
3477 uniform->descriptor = descriptor;
3478 uniform->location = bindingLocation;
3479 uniform->image = VkImageSp(new Unique<VkImage>(vkTexture));
3480 uniform->imageView = VkImageViewSp(new Unique<VkImageView>(imageView));
3481 uniform->sampler = VkSamplerSp(new Unique<VkSampler>(sampler));
3482 uniform->alloc = AllocationSp(allocation.release());
3487 SamplerUniformData::SamplerUniformData (deUint32 bindingLocation,
3488 deUint32 numSamplers,
3489 const tcu::Sampler& refSampler,
3490 const tcu::TextureFormat& texFormat,
3491 const tcu::IVec3& texSize,
3492 VkImageType imageType,
3493 VkImageViewType imageViewType,
3495 : UniformDataBase (bindingLocation)
3496 , m_numSamplers (numSamplers)
3497 , m_refSampler (refSampler)
3498 , m_texFormat (texFormat)
3499 , m_texSize (texSize)
3500 , m_imageType (imageType)
3501 , m_imageViewType (imageViewType)
3506 SamplerUniformData::~SamplerUniformData (void)
3510 void SamplerUniformData::setup (ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc) const
3512 executor.setupSamplerData(vkDevice, vk, queue, queueFamilyIndex, memAlloc, m_bindingLocation, m_numSamplers, m_refSampler, m_texFormat, m_texSize, m_imageType, m_imageViewType, m_data);