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
1194 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1196 // Create command buffer
1198 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1200 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1201 DE_NULL, // const void* pNext;
1202 0u, // VkCmdBufferOptimizeFlags flags;
1203 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1206 const VkRenderPassBeginInfo renderPassBeginInfo =
1208 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1209 DE_NULL, // const void* pNext;
1210 *renderPass, // VkRenderPass renderPass;
1211 *framebuffer, // VkFramebuffer framebuffer;
1212 { { 0, 0 }, { renderSize.x(), renderSize.y() } }, // VkRect2D renderArea;
1213 (deUint32)attachmentClearValues.size(), // deUint32 attachmentCount;
1214 &attachmentClearValues[0] // const VkClearValue* pAttachmentClearValues;
1217 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1219 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1221 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
1222 0, (const VkMemoryBarrier*)DE_NULL,
1223 0, (const VkBufferMemoryBarrier*)DE_NULL,
1224 (deUint32)colorImagePreRenderBarriers.size(), colorImagePreRenderBarriers.empty() ? DE_NULL : &colorImagePreRenderBarriers[0]);
1225 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1227 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
1228 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
1230 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
1232 std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
1234 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
1235 for (size_t i = 0; i < numberOfVertexAttributes; i++)
1237 buffers[i] = m_vertexBuffers[i].get()->get();
1240 vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
1241 vk.cmdDraw(*cmdBuffer, (deUint32)positions.size(), 1u, 0u, 0u);
1243 vk.cmdEndRenderPass(*cmdBuffer);
1244 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
1245 0, (const VkMemoryBarrier*)DE_NULL,
1246 0, (const VkBufferMemoryBarrier*)DE_NULL,
1247 (deUint32)colorImagePostRenderBarriers.size(), colorImagePostRenderBarriers.empty() ? DE_NULL : &colorImagePostRenderBarriers[0]);
1249 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1253 fence = createFence(vk, vkDevice);
1258 const VkSubmitInfo submitInfo =
1260 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
1262 0u, // waitSemaphoreCount
1263 DE_NULL, // pWaitSemaphores
1264 (const VkPipelineStageFlags*)DE_NULL,
1265 1u, // commandBufferCount
1266 &cmdBuffer.get(), // pCommandBuffers
1267 0u, // signalSemaphoreCount
1268 DE_NULL // pSignalSemaphores
1271 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1272 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1273 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), DE_TRUE, ~(0ull) /* infinity*/));
1276 // Read back result and output
1278 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(4 * sizeof(deUint32) * renderSize.x() * renderSize.y());
1279 const VkBufferCreateInfo readImageBufferParams =
1281 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1282 DE_NULL, // const void* pNext;
1283 0u, // VkBufferCreateFlags flags;
1284 imageSizeBytes, // VkDeviceSize size;
1285 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
1286 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1287 1u, // deUint32 queueFamilyCount;
1288 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1291 // constants for image copy
1292 Move<VkCommandPool> copyCmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1294 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1296 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1297 DE_NULL, // const void* pNext;
1298 0u, // VkCmdBufferOptimizeFlags flags;
1299 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1302 const VkBufferImageCopy copyParams =
1304 0u, // VkDeviceSize bufferOffset;
1305 (deUint32)renderSize.x(), // deUint32 bufferRowLength;
1306 (deUint32)renderSize.y(), // deUint32 bufferImageHeight;
1308 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
1309 0u, // deUint32 mipLevel;
1310 0u, // deUint32 arraySlice;
1311 1u, // deUint32 arraySize;
1312 }, // VkImageSubresource imageSubresource;
1313 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
1314 { renderSize.x(), renderSize.y(), 1u } // VkExtent3D imageExtent;
1317 // Read back pixels.
1318 for (int outNdx = 0; outNdx < (int)m_shaderSpec.outputs.size(); ++outNdx)
1320 const Symbol& output = m_shaderSpec.outputs[outNdx];
1321 const int outSize = output.varType.getScalarSize();
1322 const int outVecSize = glu::getDataTypeNumComponents(output.varType.getBasicType());
1323 const int outNumLocs = glu::getDataTypeNumLocations(output.varType.getBasicType());
1324 deUint32* dstPtrBase = static_cast<deUint32*>(outputs[outNdx]);
1325 const int outLocation = de::lookup(m_outputLayout.locationMap, output.name);
1327 for (int locNdx = 0; locNdx < outNumLocs; ++locNdx)
1329 tcu::TextureLevel tmpBuf;
1330 const tcu::TextureFormat format = getRenderbufferFormatForOutput(output.varType, false);
1331 const tcu::TextureFormat readFormat (tcu::TextureFormat::RGBA, format.type);
1332 const Unique<VkBuffer> readImageBuffer(createBuffer(vk, vkDevice, &readImageBufferParams));
1333 const de::UniquePtr<Allocation> readImageBufferMemory(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
1335 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
1337 // Copy image to buffer
1340 Move<VkCommandBuffer> copyCmdBuffer = allocateCommandBuffer(vk, vkDevice, *copyCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1342 const VkSubmitInfo submitInfo =
1344 VK_STRUCTURE_TYPE_SUBMIT_INFO,
1347 (const VkSemaphore*)DE_NULL,
1348 (const VkPipelineStageFlags*)DE_NULL,
1350 ©CmdBuffer.get(),
1352 (const VkSemaphore*)DE_NULL,
1355 VK_CHECK(vk.beginCommandBuffer(*copyCmdBuffer, &cmdBufferBeginInfo));
1356 vk.cmdCopyImageToBuffer(*copyCmdBuffer, colorImages[outLocation + locNdx].get()->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params);
1357 VK_CHECK(vk.endCommandBuffer(*copyCmdBuffer));
1359 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1360 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1361 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
1364 const VkMappedMemoryRange range =
1366 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
1367 DE_NULL, // const void* pNext;
1368 readImageBufferMemory->getMemory(), // VkDeviceMemory mem;
1369 0, // VkDeviceSize offset;
1370 imageSizeBytes, // VkDeviceSize size;
1373 VK_CHECK(vk.invalidateMappedMemoryRanges(vkDevice, 1u, &range));
1375 tmpBuf.setStorage(readFormat, renderSize.x(), renderSize.y());
1377 const tcu::TextureFormat resultFormat(tcu::TextureFormat::RGBA, format.type);
1378 const tcu::ConstPixelBufferAccess resultAccess(resultFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr());
1380 tcu::copy(tmpBuf.getAccess(), resultAccess);
1382 if (outSize == 4 && outNumLocs == 1)
1383 deMemcpy(dstPtrBase, tmpBuf.getAccess().getDataPtr(), numValues * outVecSize * sizeof(deUint32));
1386 for (int valNdx = 0; valNdx < numValues; valNdx++)
1388 const deUint32* srcPtr = (const deUint32*)tmpBuf.getAccess().getDataPtr() + valNdx * 4;
1389 deUint32* dstPtr = &dstPtrBase[outSize * valNdx + outVecSize * locNdx];
1390 deMemcpy(dstPtr, srcPtr, outVecSize * sizeof(deUint32));
1398 // VertexShaderExecutor
1400 class VertexShaderExecutor : public FragmentOutExecutor
1403 VertexShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1404 virtual ~VertexShaderExecutor (void);
1406 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst;}
1408 virtual void setShaderSources (SourceCollections& programCollection) const;
1412 VertexShaderExecutor::VertexShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1413 : FragmentOutExecutor (shaderSpec, shaderType)
1417 VertexShaderExecutor::~VertexShaderExecutor (void)
1421 void VertexShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1423 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShader(m_shaderSpec, "a_", "vtx_out_"));
1424 /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1425 programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(m_shaderSpec, false, m_outputLayout.locationMap, "vtx_out_", "o_"));
1428 // GeometryShaderExecutor
1430 class GeometryShaderExecutor : public FragmentOutExecutor
1433 GeometryShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1434 virtual ~GeometryShaderExecutor (void);
1436 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst; }
1438 virtual void setShaderSources (SourceCollections& programCollection) const;
1442 GeometryShaderExecutor::GeometryShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1443 : FragmentOutExecutor (shaderSpec, shaderType)
1447 GeometryShaderExecutor::~GeometryShaderExecutor (void)
1451 void GeometryShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1453 programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(m_shaderSpec.inputs, "a_", "vtx_out_"));
1455 programCollection.glslSources.add("geom") << glu::GeometrySource(generateGeometryShader(m_shaderSpec, "vtx_out_", "geom_out_"));
1457 /* \todo [2015-09-18 rsipka] set useIntOutputs parameter if needed. */
1458 programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(m_shaderSpec, false, m_outputLayout.locationMap, "geom_out_", "o_"));
1462 // FragmentShaderExecutor
1464 class FragmentShaderExecutor : public FragmentOutExecutor
1467 FragmentShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1468 virtual ~FragmentShaderExecutor (void);
1470 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst; }
1472 virtual void setShaderSources (SourceCollections& programCollection) const;
1476 FragmentShaderExecutor::FragmentShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1477 : FragmentOutExecutor (shaderSpec, shaderType)
1481 FragmentShaderExecutor::~FragmentShaderExecutor (void)
1485 void FragmentShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1487 programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(m_shaderSpec.inputs, "a_", "vtx_out_"));
1488 /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1489 programCollection.glslSources.add("frag") << glu::FragmentSource(generateFragmentShader(m_shaderSpec, false, m_outputLayout.locationMap, "vtx_out_", "o_"));
1492 // Shared utilities for compute and tess executors
1494 static deUint32 getVecStd430ByteAlignment (glu::DataType type)
1496 switch (glu::getDataTypeScalarSize(type))
1508 class BufferIoExecutor : public ShaderExecutor
1511 BufferIoExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1512 virtual ~BufferIoExecutor (void);
1514 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst; }
1519 INPUT_BUFFER_BINDING = 0,
1520 OUTPUT_BUFFER_BINDING = 1,
1523 void initBuffers (const Context& ctx, int numValues);
1524 VkBuffer getInputBuffer (void) const { return *m_inputBuffer; }
1525 VkBuffer getOutputBuffer (void) const { return *m_outputBuffer; }
1526 deUint32 getInputStride (void) const { return getLayoutStride(m_inputLayout); }
1527 deUint32 getOutputStride (void) const { return getLayoutStride(m_outputLayout); }
1529 void uploadInputBuffer (const Context& ctx, const void* const* inputPtrs, int numValues);
1530 void readOutputBuffer (const Context& ctx, void* const* outputPtrs, int numValues);
1532 static void declareBufferBlocks (std::ostream& src, const ShaderSpec& spec);
1533 static void generateExecBufferIo(std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName);
1536 Move<VkBuffer> m_inputBuffer;
1537 Move<VkBuffer> m_outputBuffer;
1544 deUint32 matrixStride;
1546 VarLayout (void) : offset(0), stride(0), matrixStride(0) {}
1549 static void computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout);
1550 static deUint32 getLayoutStride (const vector<VarLayout>& layout);
1552 static void copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1553 static void copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1555 de::MovePtr<Allocation> m_inputAlloc;
1556 de::MovePtr<Allocation> m_outputAlloc;
1558 vector<VarLayout> m_inputLayout;
1559 vector<VarLayout> m_outputLayout;
1562 BufferIoExecutor::BufferIoExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1563 : ShaderExecutor (shaderSpec, shaderType)
1565 computeVarLayout(m_shaderSpec.inputs, &m_inputLayout);
1566 computeVarLayout(m_shaderSpec.outputs, &m_outputLayout);
1569 BufferIoExecutor::~BufferIoExecutor (void)
1573 inline deUint32 BufferIoExecutor::getLayoutStride (const vector<VarLayout>& layout)
1575 return layout.empty() ? 0 : layout[0].stride;
1578 void BufferIoExecutor::computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout)
1580 deUint32 maxAlignment = 0;
1581 deUint32 curOffset = 0;
1583 DE_ASSERT(layout != DE_NULL);
1584 DE_ASSERT(layout->empty());
1585 layout->resize(symbols.size());
1587 for (size_t varNdx = 0; varNdx < symbols.size(); varNdx++)
1589 const Symbol& symbol = symbols[varNdx];
1590 const glu::DataType basicType = symbol.varType.getBasicType();
1591 VarLayout& layoutEntry = (*layout)[varNdx];
1593 if (glu::isDataTypeScalarOrVector(basicType))
1595 const deUint32 alignment = getVecStd430ByteAlignment(basicType);
1596 const deUint32 size = (deUint32)glu::getDataTypeScalarSize(basicType) * (int)sizeof(deUint32);
1598 curOffset = (deUint32)deAlign32((int)curOffset, (int)alignment);
1599 maxAlignment = de::max(maxAlignment, alignment);
1601 layoutEntry.offset = curOffset;
1602 layoutEntry.matrixStride = 0;
1606 else if (glu::isDataTypeMatrix(basicType))
1608 const int numVecs = glu::getDataTypeMatrixNumColumns(basicType);
1609 const glu::DataType vecType = glu::getDataTypeFloatVec(glu::getDataTypeMatrixNumRows(basicType));
1610 const deUint32 vecAlignment = getVecStd430ByteAlignment(vecType);
1612 curOffset = (deUint32)deAlign32((int)curOffset, (int)vecAlignment);
1613 maxAlignment = de::max(maxAlignment, vecAlignment);
1615 layoutEntry.offset = curOffset;
1616 layoutEntry.matrixStride = vecAlignment;
1618 curOffset += vecAlignment*numVecs;
1625 const deUint32 totalSize = (deUint32)deAlign32(curOffset, maxAlignment);
1627 for (vector<VarLayout>::iterator varIter = layout->begin(); varIter != layout->end(); ++varIter)
1628 varIter->stride = totalSize;
1632 void BufferIoExecutor::declareBufferBlocks (std::ostream& src, const ShaderSpec& spec)
1635 if (!spec.inputs.empty())
1637 glu::StructType inputStruct("Inputs");
1638 for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1639 inputStruct.addMember(symIter->name.c_str(), symIter->varType);
1640 src << glu::declare(&inputStruct) << ";\n";
1645 glu::StructType outputStruct("Outputs");
1646 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1647 outputStruct.addMember(symIter->name.c_str(), symIter->varType);
1648 src << glu::declare(&outputStruct) << ";\n";
1653 if (!spec.inputs.empty())
1655 src << "layout(set = 0, binding = " << int(INPUT_BUFFER_BINDING) << ", std430) buffer InBuffer\n"
1657 << " Inputs inputs[];\n"
1661 src << "layout(set = 0, binding = " << int(OUTPUT_BUFFER_BINDING) << ", std430) buffer OutBuffer\n"
1663 << " Outputs outputs[];\n"
1668 void BufferIoExecutor::generateExecBufferIo (std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName)
1670 for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1671 src << "\t" << glu::declare(symIter->varType, symIter->name) << " = inputs[" << invocationNdxName << "]." << symIter->name << ";\n";
1673 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1674 src << "\t" << glu::declare(symIter->varType, symIter->name) << ";\n";
1679 std::istringstream opSrc (spec.source);
1682 while (std::getline(opSrc, line))
1683 src << "\t" << line << "\n";
1687 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1688 src << "\toutputs[" << invocationNdxName << "]." << symIter->name << " = " << symIter->name << ";\n";
1691 void BufferIoExecutor::copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1693 if (varType.isBasicType())
1695 const glu::DataType basicType = varType.getBasicType();
1696 const bool isMatrix = glu::isDataTypeMatrix(basicType);
1697 const int scalarSize = glu::getDataTypeScalarSize(basicType);
1698 const int numVecs = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1699 const int numComps = scalarSize / numVecs;
1701 for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1703 for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1705 const int srcOffset = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1706 const int dstOffset = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1707 const deUint8* srcPtr = (const deUint8*)srcBasePtr + srcOffset;
1708 deUint8* dstPtr = (deUint8*)dstBasePtr + dstOffset;
1710 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1715 throw tcu::InternalError("Unsupported type");
1718 void BufferIoExecutor::copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1720 if (varType.isBasicType())
1722 const glu::DataType basicType = varType.getBasicType();
1723 const bool isMatrix = glu::isDataTypeMatrix(basicType);
1724 const int scalarSize = glu::getDataTypeScalarSize(basicType);
1725 const int numVecs = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1726 const int numComps = scalarSize / numVecs;
1728 for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1730 for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1732 const int srcOffset = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1733 const int dstOffset = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1734 const deUint8* srcPtr = (const deUint8*)srcBasePtr + srcOffset;
1735 deUint8* dstPtr = (deUint8*)dstBasePtr + dstOffset;
1737 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1742 throw tcu::InternalError("Unsupported type");
1745 void BufferIoExecutor::uploadInputBuffer (const Context& ctx, const void* const* inputPtrs, int numValues)
1747 const VkDevice vkDevice = ctx.getDevice();
1748 const DeviceInterface& vk = ctx.getDeviceInterface();
1750 const deUint32 inputStride = getLayoutStride(m_inputLayout);
1751 const int inputBufferSize = inputStride * numValues;
1753 if (inputBufferSize == 0)
1754 return; // No inputs
1756 DE_ASSERT(m_shaderSpec.inputs.size() == m_inputLayout.size());
1757 for (size_t inputNdx = 0; inputNdx < m_shaderSpec.inputs.size(); ++inputNdx)
1759 const glu::VarType& varType = m_shaderSpec.inputs[inputNdx].varType;
1760 const VarLayout& layout = m_inputLayout[inputNdx];
1762 copyToBuffer(varType, layout, numValues, inputPtrs[inputNdx], m_inputAlloc->getHostPtr());
1765 flushMappedMemoryRange(vk, vkDevice, m_inputAlloc->getMemory(), m_inputAlloc->getOffset(), inputBufferSize);
1768 void BufferIoExecutor::readOutputBuffer (const Context& ctx, void* const* outputPtrs, int numValues)
1770 const VkDevice vkDevice = ctx.getDevice();
1771 const DeviceInterface& vk = ctx.getDeviceInterface();
1773 const deUint32 outputStride = getLayoutStride(m_outputLayout);
1774 const int outputBufferSize = numValues * outputStride;
1776 DE_ASSERT(outputBufferSize > 0); // At least some outputs are required.
1778 invalidateMappedMemoryRange(vk, vkDevice, m_outputAlloc->getMemory(), m_outputAlloc->getOffset(), outputBufferSize);
1780 DE_ASSERT(m_shaderSpec.outputs.size() == m_outputLayout.size());
1781 for (size_t outputNdx = 0; outputNdx < m_shaderSpec.outputs.size(); ++outputNdx)
1783 const glu::VarType& varType = m_shaderSpec.outputs[outputNdx].varType;
1784 const VarLayout& layout = m_outputLayout[outputNdx];
1786 copyFromBuffer(varType, layout, numValues, m_outputAlloc->getHostPtr(), outputPtrs[outputNdx]);
1790 void BufferIoExecutor::initBuffers (const Context& ctx, int numValues)
1792 const deUint32 inputStride = getLayoutStride(m_inputLayout);
1793 const deUint32 outputStride = getLayoutStride(m_outputLayout);
1794 // Avoid creating zero-sized buffer/memory
1795 const size_t inputBufferSize = numValues * inputStride ? (numValues * inputStride) : 1;
1796 const size_t outputBufferSize = numValues * outputStride;
1798 // Upload data to buffer
1799 const VkDevice vkDevice = ctx.getDevice();
1800 const DeviceInterface& vk = ctx.getDeviceInterface();
1801 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex();
1802 Allocator& memAlloc = ctx.getDefaultAllocator();
1804 const VkBufferCreateInfo inputBufferParams =
1806 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1807 DE_NULL, // const void* pNext;
1808 0u, // VkBufferCreateFlags flags;
1809 inputBufferSize, // VkDeviceSize size;
1810 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
1811 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1812 1u, // deUint32 queueFamilyCount;
1813 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1816 m_inputBuffer = createBuffer(vk, vkDevice, &inputBufferParams);
1817 m_inputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_inputBuffer), MemoryRequirement::HostVisible);
1819 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_inputBuffer, m_inputAlloc->getMemory(), m_inputAlloc->getOffset()));
1821 const VkBufferCreateInfo outputBufferParams =
1823 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1824 DE_NULL, // const void* pNext;
1825 0u, // VkBufferCreateFlags flags;
1826 outputBufferSize, // VkDeviceSize size;
1827 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
1828 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1829 1u, // deUint32 queueFamilyCount;
1830 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1833 m_outputBuffer = createBuffer(vk, vkDevice, &outputBufferParams);
1834 m_outputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_outputBuffer), MemoryRequirement::HostVisible);
1836 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_outputBuffer, m_outputAlloc->getMemory(), m_outputAlloc->getOffset()));
1839 // ComputeShaderExecutor
1841 class ComputeShaderExecutor : public BufferIoExecutor
1844 ComputeShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1845 virtual ~ComputeShaderExecutor (void);
1847 virtual void setShaderSources (SourceCollections& programCollection) const;
1849 virtual void execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs);
1852 static std::string generateComputeShader (const ShaderSpec& spec);
1855 ComputeShaderExecutor::ComputeShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1856 : BufferIoExecutor (shaderSpec, shaderType)
1860 ComputeShaderExecutor::~ComputeShaderExecutor (void)
1864 std::string ComputeShaderExecutor::generateComputeShader (const ShaderSpec& spec)
1866 std::ostringstream src;
1867 src << "#version 310 es\n";
1869 if (!spec.globalDeclarations.empty())
1870 src << spec.globalDeclarations << "\n";
1872 src << "layout(local_size_x = 1) in;\n"
1875 declareBufferBlocks(src, spec);
1877 src << "void main (void)\n"
1879 << " uint invocationNdx = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z\n"
1880 << " + gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n";
1882 generateExecBufferIo(src, spec, "invocationNdx");
1889 void ComputeShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1891 programCollection.glslSources.add("compute") << glu::ComputeSource(generateComputeShader(m_shaderSpec));
1894 void ComputeShaderExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs)
1896 checkSupported(ctx, m_shaderType);
1898 const VkDevice vkDevice = ctx.getDevice();
1899 const DeviceInterface& vk = ctx.getDeviceInterface();
1900 const VkQueue queue = ctx.getUniversalQueue();
1901 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex();
1902 Allocator& memAlloc = ctx.getDefaultAllocator();
1904 Move<VkShaderModule> computeShaderModule;
1905 Move<VkPipeline> computePipeline;
1906 Move<VkPipelineLayout> pipelineLayout;
1907 Move<VkCommandPool> cmdPool;
1908 Move<VkDescriptorPool> descriptorPool;
1909 Move<VkDescriptorSetLayout> descriptorSetLayout;
1910 Move<VkDescriptorSet> descriptorSet;
1911 Move<VkFence> fence;
1913 initBuffers(ctx, numValues);
1915 // Setup input buffer & copy data
1916 uploadInputBuffer(ctx, inputs, numValues);
1918 // Create command pool
1919 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1921 // Create command buffer
1922 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1924 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1925 DE_NULL, // const void* pNext;
1926 0u, // VkCmdBufferOptimizeFlags flags;
1927 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1930 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1931 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1932 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1933 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1935 addUniforms(vkDevice, vk, queue, queueFamilyIndex, memAlloc);
1937 descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
1938 descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1940 const VkDescriptorSetAllocateInfo allocInfo =
1942 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1946 &*descriptorSetLayout
1949 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
1951 // Create pipeline layout
1953 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1955 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1956 DE_NULL, // const void* pNext;
1957 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
1958 1u, // deUint32 CdescriptorSetCount;
1959 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
1960 0u, // deUint32 pushConstantRangeCount;
1961 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1964 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1969 computeShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("compute"), 0);
1974 const VkPipelineShaderStageCreateInfo shaderStageParams[1] =
1977 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1978 DE_NULL, // const void* pNext;
1979 (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
1980 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagsBit stage;
1981 *computeShaderModule, // VkShaderModule shader;
1982 "main", // const char* pName;
1983 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1987 const VkComputePipelineCreateInfo computePipelineParams =
1989 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
1990 DE_NULL, // const void* pNext;
1991 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
1992 *shaderStageParams, // VkPipelineShaderStageCreateInfo cs;
1993 *pipelineLayout, // VkPipelineLayout layout;
1994 0u, // VkPipeline basePipelineHandle;
1995 0u, // int32_t basePipelineIndex;
1998 computePipeline = createComputePipeline(vk, vkDevice, DE_NULL, &computePipelineParams);
2002 fence = createFence(vk, vkDevice);
2004 const int maxValuesPerInvocation = ctx.getDeviceProperties().limits.maxComputeWorkGroupSize[0];
2006 const deUint32 inputStride = getInputStride();
2007 const deUint32 outputStride = getOutputStride();
2009 while (curOffset < numValues)
2011 Move<VkCommandBuffer> cmdBuffer;
2012 const int numToExec = de::min(maxValuesPerInvocation, numValues-curOffset);
2014 // Update descriptors
2016 DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2018 const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2020 *m_outputBuffer, // VkBuffer buffer;
2021 curOffset * outputStride, // VkDeviceSize offset;
2022 numToExec * outputStride // VkDeviceSize range;
2025 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2029 const VkDescriptorBufferInfo inputDescriptorBufferInfo =
2031 *m_inputBuffer, // VkBuffer buffer;
2032 curOffset * inputStride, // VkDeviceSize offset;
2033 numToExec * inputStride // VkDeviceSize range;
2036 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2039 uploadUniforms(descriptorSetUpdateBuilder, *descriptorSet);
2041 descriptorSetUpdateBuilder.update(vk, vkDevice);
2044 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2045 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2046 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
2048 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
2050 vk.cmdDispatch(*cmdBuffer, numToExec, 1, 1);
2052 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2054 curOffset += numToExec;
2058 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2060 const VkSubmitInfo submitInfo =
2062 VK_STRUCTURE_TYPE_SUBMIT_INFO,
2065 (const VkSemaphore*)DE_NULL,
2066 (const VkPipelineStageFlags*)DE_NULL,
2070 (const VkSemaphore*)DE_NULL,
2073 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2074 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2079 readOutputBuffer(ctx, outputs, numValues);
2082 // Tessellation utils
2084 static std::string generateVertexShaderForTess (void)
2086 std::ostringstream src;
2087 src << "#version 310 es\n"
2088 << "void main (void)\n{\n"
2089 << " gl_Position = vec4(gl_VertexIndex/2, gl_VertexIndex%2, 0.0, 1.0);\n"
2095 class TessellationExecutor : public BufferIoExecutor
2098 TessellationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
2099 virtual ~TessellationExecutor (void);
2101 void renderTess (const Context& ctx, deUint32 numValues, deUint32 vertexCount, deUint32 patchControlPoints);
2104 TessellationExecutor::TessellationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2105 : BufferIoExecutor (shaderSpec, shaderType)
2109 TessellationExecutor::~TessellationExecutor (void)
2113 void TessellationExecutor::renderTess (const Context& ctx, deUint32 numValues, deUint32 vertexCount, deUint32 patchControlPoints)
2115 const size_t inputBufferSize = numValues * getInputStride();
2116 const VkDevice vkDevice = ctx.getDevice();
2117 const DeviceInterface& vk = ctx.getDeviceInterface();
2118 const VkQueue queue = ctx.getUniversalQueue();
2119 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex();
2120 Allocator& memAlloc = ctx.getDefaultAllocator();
2122 const tcu::UVec2 renderSize (DEFAULT_RENDER_WIDTH, DEFAULT_RENDER_HEIGHT);
2124 Move<VkImage> colorImage;
2125 de::MovePtr<Allocation> colorImageAlloc;
2126 VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
2127 Move<VkImageView> colorImageView;
2129 Move<VkRenderPass> renderPass;
2130 Move<VkFramebuffer> framebuffer;
2131 Move<VkPipelineLayout> pipelineLayout;
2132 Move<VkPipeline> graphicsPipeline;
2134 Move<VkShaderModule> vertexShaderModule;
2135 Move<VkShaderModule> tessControlShaderModule;
2136 Move<VkShaderModule> tessEvalShaderModule;
2137 Move<VkShaderModule> fragmentShaderModule;
2139 Move<VkCommandPool> cmdPool;
2140 Move<VkCommandBuffer> cmdBuffer;
2142 Move<VkFence> fence;
2144 Move<VkDescriptorPool> descriptorPool;
2145 Move<VkDescriptorSetLayout> descriptorSetLayout;
2146 Move<VkDescriptorSet> descriptorSet;
2148 // Create color image
2150 const VkImageCreateInfo colorImageParams =
2152 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2153 DE_NULL, // const void* pNext;
2154 0u, // VkImageCreateFlags flags;
2155 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2156 colorFormat, // VkFormat format;
2157 { renderSize.x(), renderSize.y(), 1u }, // VkExtent3D extent;
2158 1u, // deUint32 mipLevels;
2159 1u, // deUint32 arraySize;
2160 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2161 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2162 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
2163 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2164 1u, // deUint32 queueFamilyCount;
2165 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2166 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
2169 colorImage = createImage(vk, vkDevice, &colorImageParams);
2171 // Allocate and bind color image memory
2172 colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *colorImage), MemoryRequirement::Any);
2173 VK_CHECK(vk.bindImageMemory(vkDevice, *colorImage, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
2176 // Create color attachment view
2178 const VkImageViewCreateInfo colorImageViewParams =
2180 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2181 DE_NULL, // const void* pNext;
2182 0u, // VkImageViewCreateFlags flags;
2183 *colorImage, // VkImage image;
2184 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2185 colorFormat, // VkFormat format;
2187 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
2188 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
2189 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
2190 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
2191 }, // VkComponentsMapping components;
2193 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2194 0u, // deUint32 baseMipLevel;
2195 1u, // deUint32 mipLevels;
2196 0u, // deUint32 baseArraylayer;
2197 1u // deUint32 layerCount;
2198 } // VkImageSubresourceRange subresourceRange;
2201 colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
2204 // Create render pass
2206 const VkAttachmentDescription colorAttachmentDescription =
2208 0u, // VkAttachmentDescriptorFlags flags;
2209 colorFormat, // VkFormat format;
2210 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2211 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
2212 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2213 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2214 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
2215 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2216 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
2219 const VkAttachmentDescription attachments[1] =
2221 colorAttachmentDescription
2224 const VkAttachmentReference colorAttachmentReference =
2226 0u, // deUint32 attachment;
2227 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
2230 const VkSubpassDescription subpassDescription =
2232 0u, // VkSubpassDescriptionFlags flags;
2233 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
2234 0u, // deUint32 inputCount;
2235 DE_NULL, // const VkAttachmentReference* pInputAttachments;
2236 1u, // deUint32 colorCount;
2237 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
2238 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
2239 DE_NULL, // VkAttachmentReference depthStencilAttachment;
2240 0u, // deUint32 preserveCount;
2241 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
2244 const VkRenderPassCreateInfo renderPassParams =
2246 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
2247 DE_NULL, // const void* pNext;
2248 0u, // VkRenderPassCreateFlags flags;
2249 1u, // deUint32 attachmentCount;
2250 attachments, // const VkAttachmentDescription* pAttachments;
2251 1u, // deUint32 subpassCount;
2252 &subpassDescription, // const VkSubpassDescription* pSubpasses;
2253 0u, // deUint32 dependencyCount;
2254 DE_NULL // const VkSubpassDependency* pDependencies;
2257 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
2260 // Create framebuffer
2262 const VkFramebufferCreateInfo framebufferParams =
2264 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
2265 DE_NULL, // const void* pNext;
2266 0u, // VkFramebufferCreateFlags flags;
2267 *renderPass, // VkRenderPass renderPass;
2268 1u, // deUint32 attachmentCount;
2269 &*colorImageView, // const VkAttachmentBindInfo* pAttachments;
2270 (deUint32)renderSize.x(), // deUint32 width;
2271 (deUint32)renderSize.y(), // deUint32 height;
2272 1u // deUint32 layers;
2275 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
2278 // Create descriptors
2280 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2281 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2282 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2283 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2285 addUniforms(vkDevice, vk, queue, queueFamilyIndex, memAlloc);
2287 descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
2288 descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2290 const VkDescriptorSetAllocateInfo allocInfo =
2292 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2296 &*descriptorSetLayout
2299 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2300 // Update descriptors
2302 DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2303 const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2305 *m_outputBuffer, // VkBuffer buffer;
2306 0u, // VkDeviceSize offset;
2307 VK_WHOLE_SIZE // VkDeviceSize range;
2310 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2312 VkDescriptorBufferInfo inputDescriptorBufferInfo =
2314 0, // VkBuffer buffer;
2315 0u, // VkDeviceSize offset;
2316 VK_WHOLE_SIZE // VkDeviceSize range;
2319 if (inputBufferSize > 0)
2321 inputDescriptorBufferInfo.buffer = *m_inputBuffer;
2323 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2326 uploadUniforms(descriptorSetUpdateBuilder, *descriptorSet);
2328 descriptorSetUpdateBuilder.update(vk, vkDevice);
2332 // Create pipeline layout
2334 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2336 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
2337 DE_NULL, // const void* pNext;
2338 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
2339 1u, // deUint32 descriptorSetCount;
2340 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
2341 0u, // deUint32 pushConstantRangeCount;
2342 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
2345 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2348 // Create shader modules
2350 vertexShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("vert"), 0);
2351 tessControlShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("tess_control"), 0);
2352 tessEvalShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("tess_eval"), 0);
2353 fragmentShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("frag"), 0);
2358 const VkPipelineShaderStageCreateInfo shaderStageParams[4] =
2361 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2362 DE_NULL, // const void* pNext;
2363 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2364 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBit stage;
2365 *vertexShaderModule, // VkShaderModule shader;
2366 "main", // const char* pName;
2367 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2370 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2371 DE_NULL, // const void* pNext;
2372 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2373 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, // VkShaderStageFlagBit stage;
2374 *tessControlShaderModule, // VkShaderModule shader;
2375 "main", // const char* pName;
2376 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2379 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2380 DE_NULL, // const void* pNext;
2381 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2382 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, // VkShaderStageFlagBit stage;
2383 *tessEvalShaderModule, // VkShaderModule shader;
2384 "main", // const char* pName;
2385 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2388 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2389 DE_NULL, // const void* pNext;
2390 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2391 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBit stage;
2392 *fragmentShaderModule, // VkShaderModule shader;
2393 "main", // const char* pName;
2394 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2398 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
2400 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
2401 DE_NULL, // const void* pNext;
2402 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
2403 0u, // deUint32 bindingCount;
2404 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
2405 0u, // deUint32 attributeCount;
2406 DE_NULL, // const VkVertexInputAttributeDescription* pvertexAttributeDescriptions;
2409 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
2411 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
2412 DE_NULL, // const void* pNext;
2413 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2414 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, // VkPrimitiveTopology topology;
2415 DE_FALSE // VkBool32 primitiveRestartEnable;
2418 struct VkPipelineTessellationStateCreateInfo tessellationStateParams =
2420 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
2421 DE_NULL, // const void* pNext;
2422 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags;
2423 patchControlPoints // uint32_t patchControlPoints;
2426 const VkViewport viewport =
2428 0.0f, // float originX;
2429 0.0f, // float originY;
2430 (float)renderSize.x(), // float width;
2431 (float)renderSize.y(), // float height;
2432 0.0f, // float minDepth;
2433 1.0f // float maxDepth;
2436 const VkRect2D scissor =
2441 }, // VkOffset2D offset;
2443 renderSize.x(), // deUint32 width;
2444 renderSize.y(), // deUint32 height;
2445 }, // VkExtent2D extent;
2448 const VkPipelineViewportStateCreateInfo viewportStateParams =
2450 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
2451 DE_NULL, // const void* pNext;
2452 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewPortStateCreateFlags flags;
2453 1u, // deUint32 viewportCount;
2454 &viewport, // const VkViewport* pViewports;
2455 1u, // deUint32 scissorsCount;
2456 &scissor // const VkRect2D* pScissors;
2459 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
2461 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
2462 DE_NULL, // const void* pNext;
2463 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStageCreateFlags flags;
2464 VK_FALSE, // VkBool32 depthClipEnable;
2465 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
2466 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
2467 VK_CULL_MODE_NONE, // VkCullMode cullMode;
2468 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
2469 VK_FALSE, // VkBool32 depthBiasEnable;
2470 0.0f, // float depthBias;
2471 0.0f, // float depthBiasClamp;
2472 0.0f, // float slopeScaledDepthBias;
2473 1.0f // float lineWidth;
2476 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
2478 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
2479 DE_NULL, // const void* pNext;
2480 0u, // VkPipelineMultisampleStateCreateFlags flags;
2481 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
2482 VK_FALSE, // VkBool32 sampleShadingEnable;
2483 0.0f, // float minSampleShading;
2484 DE_NULL, // const VkSampleMask* pSampleMask;
2485 VK_FALSE, // VkBool32 alphaToCoverageEnable;
2486 VK_FALSE // VkBool32 alphaToOneEnable;
2489 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
2491 VK_FALSE, // VkBool32 blendEnable;
2492 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcBlendColor;
2493 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destBlendColor;
2494 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
2495 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcBlendAlpha;
2496 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destBlendAlpha;
2497 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
2498 (VK_COLOR_COMPONENT_R_BIT |
2499 VK_COLOR_COMPONENT_G_BIT |
2500 VK_COLOR_COMPONENT_B_BIT |
2501 VK_COLOR_COMPONENT_A_BIT) // VkColorComponentFlags colorWriteMask;
2504 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
2506 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
2507 DE_NULL, // const void* pNext;
2508 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags
2509 VK_FALSE, // VkBool32 logicOpEnable;
2510 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
2511 1u, // deUint32 attachmentCount;
2512 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
2513 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConst[4];
2516 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
2518 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
2519 DE_NULL, // const void* pNext;
2520 0u, // VkPipelineCreateFlags flags;
2521 4u, // deUint32 stageCount;
2522 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages;
2523 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
2524 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
2525 &tessellationStateParams, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
2526 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
2527 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
2528 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
2529 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
2530 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
2531 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
2532 *pipelineLayout, // VkPipelineLayout layout;
2533 *renderPass, // VkRenderPass renderPass;
2534 0u, // deUint32 subpass;
2535 0u, // VkPipeline basePipelineHandle;
2536 0u // deInt32 basePipelineIndex;
2539 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
2542 // Create command pool
2543 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
2545 // Create command buffer
2547 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
2549 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
2550 DE_NULL, // const void* pNext;
2551 0u, // VkCmdBufferOptimizeFlags flags;
2552 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2555 const VkClearValue clearValues[1] =
2557 getDefaultClearColor()
2560 const VkRenderPassBeginInfo renderPassBeginInfo =
2562 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
2563 DE_NULL, // const void* pNext;
2564 *renderPass, // VkRenderPass renderPass;
2565 *framebuffer, // VkFramebuffer framebuffer;
2566 { { 0, 0 }, { renderSize.x(), renderSize.y() } }, // VkRect2D renderArea;
2567 1, // deUint32 attachmentCount;
2568 clearValues // const VkClearValue* pClearValues;
2571 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2573 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2575 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2577 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
2579 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
2581 vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
2583 vk.cmdEndRenderPass(*cmdBuffer);
2584 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2588 fence = createFence(vk, vkDevice);
2592 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2593 const VkSubmitInfo submitInfo =
2595 VK_STRUCTURE_TYPE_SUBMIT_INFO,
2598 (const VkSemaphore*)0,
2599 (const VkPipelineStageFlags*)DE_NULL,
2603 (const VkSemaphore*)0,
2605 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2606 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2610 // TessControlExecutor
2612 class TessControlExecutor : public TessellationExecutor
2615 TessControlExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
2616 virtual ~TessControlExecutor (void);
2618 virtual void setShaderSources (SourceCollections& programCollection) const;
2620 virtual void execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs);
2623 static std::string generateTessControlShader (const ShaderSpec& shaderSpec);
2626 TessControlExecutor::TessControlExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2627 : TessellationExecutor (shaderSpec, shaderType)
2631 TessControlExecutor::~TessControlExecutor (void)
2635 std::string TessControlExecutor::generateTessControlShader (const ShaderSpec& shaderSpec)
2637 std::ostringstream src;
2638 src << "#version 310 es\n"
2639 "#extension GL_EXT_tessellation_shader : require\n\n";
2641 if (!shaderSpec.globalDeclarations.empty())
2642 src << shaderSpec.globalDeclarations << "\n";
2644 src << "\nlayout(vertices = 1) out;\n\n";
2646 declareBufferBlocks(src, shaderSpec);
2648 src << "void main (void)\n{\n";
2650 for (int ndx = 0; ndx < 2; ndx++)
2651 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2653 for (int ndx = 0; ndx < 4; ndx++)
2654 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2657 << "\thighp uint invocationId = uint(gl_PrimitiveID);\n";
2659 generateExecBufferIo(src, shaderSpec, "invocationId");
2666 static std::string generateEmptyTessEvalShader ()
2668 std::ostringstream src;
2670 src << "#version 310 es\n"
2671 "#extension GL_EXT_tessellation_shader : require\n\n";
2673 src << "layout(triangles, ccw) in;\n";
2675 src << "\nvoid main (void)\n{\n"
2676 << "\tgl_Position = vec4(gl_TessCoord.xy, 0.0, 1.0);\n"
2682 void TessControlExecutor::setShaderSources (SourceCollections& programCollection) const
2684 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess());
2685 programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generateTessControlShader(m_shaderSpec));
2686 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateEmptyTessEvalShader());
2687 programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource());
2690 void TessControlExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs)
2692 const deUint32 patchSize = 3;
2694 checkSupported(ctx, m_shaderType);
2696 initBuffers(ctx, numValues);
2698 // Setup input buffer & copy data
2699 uploadInputBuffer(ctx, inputs, numValues);
2701 renderTess(ctx, numValues, patchSize * numValues, patchSize);
2704 readOutputBuffer(ctx, outputs, numValues);
2707 // TessEvaluationExecutor
2709 class TessEvaluationExecutor : public TessellationExecutor
2712 TessEvaluationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
2713 virtual ~TessEvaluationExecutor (void);
2715 virtual void setShaderSources (SourceCollections& programCollection) const;
2717 virtual void execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs);
2720 static std::string generateTessEvalShader (const ShaderSpec& shaderSpec);
2723 TessEvaluationExecutor::TessEvaluationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2724 : TessellationExecutor (shaderSpec, shaderType)
2728 TessEvaluationExecutor::~TessEvaluationExecutor (void)
2732 static std::string generatePassthroughTessControlShader (void)
2734 std::ostringstream src;
2736 src << "#version 310 es\n"
2737 "#extension GL_EXT_tessellation_shader : require\n\n";
2739 src << "layout(vertices = 1) out;\n\n";
2741 src << "void main (void)\n{\n";
2743 for (int ndx = 0; ndx < 2; ndx++)
2744 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2746 for (int ndx = 0; ndx < 4; ndx++)
2747 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2754 std::string TessEvaluationExecutor::generateTessEvalShader (const ShaderSpec& shaderSpec)
2756 std::ostringstream src;
2758 src << "#version 310 es\n"
2759 "#extension GL_EXT_tessellation_shader : require\n\n";
2761 if (!shaderSpec.globalDeclarations.empty())
2762 src << shaderSpec.globalDeclarations << "\n";
2766 src << "layout(isolines, equal_spacing) in;\n\n";
2768 declareBufferBlocks(src, shaderSpec);
2770 src << "void main (void)\n{\n"
2771 << "\tgl_Position = vec4(gl_TessCoord.x, 0.0, 0.0, 1.0);\n"
2772 << "\thighp uint invocationId = uint(gl_PrimitiveID)*2u + (gl_TessCoord.x > 0.5 ? 1u : 0u);\n";
2774 generateExecBufferIo(src, shaderSpec, "invocationId");
2781 void TessEvaluationExecutor::setShaderSources (SourceCollections& programCollection) const
2783 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess());
2784 programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generatePassthroughTessControlShader());
2785 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateTessEvalShader(m_shaderSpec));
2786 programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource());
2789 void TessEvaluationExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs)
2791 checkSupported(ctx, m_shaderType);
2793 const int patchSize = 2;
2794 const int alignedValues = deAlign32(numValues, patchSize);
2796 // Initialize buffers with aligned value count to make room for padding
2797 initBuffers(ctx, alignedValues);
2799 // Setup input buffer & copy data
2800 uploadInputBuffer(ctx, inputs, numValues);
2802 renderTess(ctx, (deUint32)alignedValues, (deUint32)alignedValues, (deUint32)patchSize);
2805 readOutputBuffer(ctx, outputs, numValues);
2812 ShaderExecutor::ShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2813 : m_shaderSpec (shaderSpec)
2814 , m_shaderType (shaderType)
2818 ShaderExecutor::~ShaderExecutor (void)
2824 ShaderExecutor* createExecutor (glu::ShaderType shaderType, const ShaderSpec& shaderSpec)
2828 case glu::SHADERTYPE_VERTEX: return new VertexShaderExecutor (shaderSpec, shaderType);
2829 case glu::SHADERTYPE_TESSELLATION_CONTROL: return new TessControlExecutor (shaderSpec, shaderType);
2830 case glu::SHADERTYPE_TESSELLATION_EVALUATION: return new TessEvaluationExecutor (shaderSpec, shaderType);
2831 case glu::SHADERTYPE_GEOMETRY: return new GeometryShaderExecutor (shaderSpec, shaderType);
2832 case glu::SHADERTYPE_FRAGMENT: return new FragmentShaderExecutor (shaderSpec, shaderType);
2833 case glu::SHADERTYPE_COMPUTE: return new ComputeShaderExecutor (shaderSpec, shaderType);
2835 throw tcu::InternalError("Unsupported shader type");
2839 de::MovePtr<ShaderExecutor::BufferUniform> ShaderExecutor::createBufferUniform (const VkDevice& vkDevice,
2840 const DeviceInterface& vk,
2841 const VkQueue /*queue*/,
2842 const deUint32 queueFamilyIndex,
2843 Allocator& memAlloc,
2844 deUint32 bindingLocation,
2845 VkDescriptorType descriptorType,
2847 const void* dataPtr)
2849 DE_ASSERT(descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2851 VkImageUsageFlags usage = descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
2853 const VkBufferCreateInfo uniformBufferParams =
2855 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2856 DE_NULL, // const void* pNext;
2857 0u, // VkBufferCreateFlags flags;
2858 size, // VkDeviceSize size;
2859 usage, // VkBufferUsageFlags usage;
2860 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2861 1u, // deUint32 queueFamilyIndexCount;
2862 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
2865 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &uniformBufferParams);
2866 de::MovePtr<Allocation> alloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
2867 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
2869 deMemcpy(alloc->getHostPtr(), dataPtr, size);
2870 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), size);
2872 de::MovePtr<BufferUniform> uniformInfo(new BufferUniform());
2873 uniformInfo->type = descriptorType;
2874 uniformInfo->descriptor = makeDescriptorBufferInfo(*buffer, 0u, size);
2875 uniformInfo->location = bindingLocation;
2876 uniformInfo->buffer = VkBufferSp(new Unique<VkBuffer>(buffer));
2877 uniformInfo->alloc = AllocationSp(alloc.release());
2882 void ShaderExecutor::setupUniformData (const VkDevice& vkDevice,
2883 const DeviceInterface& vk,
2884 const VkQueue queue,
2885 const deUint32 queueFamilyIndex,
2886 Allocator& memAlloc,
2887 deUint32 bindingLocation,
2888 VkDescriptorType descriptorType,
2890 const void* dataPtr)
2892 de::MovePtr<BufferUniform> uniform = createBufferUniform(vkDevice, vk, queue, queueFamilyIndex, memAlloc, bindingLocation, descriptorType, size, dataPtr);
2894 m_descriptorSetLayoutBuilder.addSingleBinding(descriptorType, VK_SHADER_STAGE_ALL);
2895 m_descriptorPoolBuilder.addType(descriptorType);
2897 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform)));
2900 void ShaderExecutor::setupUniformArray (const VkDevice& vkDevice,
2901 const DeviceInterface& vk,
2902 const VkQueue queue,
2903 const deUint32 queueFamilyIndex,
2904 Allocator& memAlloc,
2905 deUint32 bindingLocation,
2906 VkDescriptorType descriptorType,
2909 const void* dataPtr)
2911 DE_ASSERT(arraySize > 0);
2913 de::MovePtr<BufferArrayUniform> bufferArray (new BufferArrayUniform());
2915 bufferArray->type = descriptorType;
2916 bufferArray->location = bindingLocation;
2918 for (deUint32 ndx = 0; ndx < arraySize; ++ndx)
2920 const void* bufferData = ((deUint8*)dataPtr) + (ndx * size);
2921 de::MovePtr<BufferUniform> uniform = createBufferUniform(vkDevice, vk, queue, queueFamilyIndex, memAlloc, bindingLocation, descriptorType, size, bufferData);
2923 bufferArray->uniforms.push_back(BufferUniformSp(new de::UniquePtr<BufferUniform>(uniform)));
2926 m_descriptorSetLayoutBuilder.addArrayBinding(descriptorType, arraySize, VK_SHADER_STAGE_ALL);
2927 m_descriptorPoolBuilder.addType(descriptorType, arraySize);
2929 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(bufferArray)));
2932 void ShaderExecutor::setupSamplerData (const VkDevice& vkDevice,
2933 const DeviceInterface& vk,
2934 const VkQueue queue,
2935 const deUint32 queueFamilyIndex,
2936 Allocator& memAlloc,
2937 deUint32 bindingLocation,
2938 deUint32 numSamplers,
2939 const tcu::Sampler& refSampler,
2940 const tcu::TextureFormat& texFormat,
2941 const tcu::IVec3& texSize,
2942 VkImageType imageType,
2943 VkImageViewType imageViewType,
2946 DE_ASSERT(numSamplers > 0);
2948 de::MovePtr<SamplerArrayUniform> samplers (new SamplerArrayUniform());
2950 samplers->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
2951 samplers->location = bindingLocation;
2953 for (deUint32 ndx = 0; ndx < numSamplers; ++ndx)
2955 const int offset = ndx * texSize.x() * texSize.y() * texSize.z() * texFormat.getPixelSize();
2956 const void* samplerData = ((deUint8*)data) + offset;
2957 de::MovePtr<SamplerUniform> uniform = createSamplerUniform(vkDevice, vk, queue, queueFamilyIndex, memAlloc, bindingLocation, refSampler, texFormat, texSize, imageType, imageViewType, samplerData);
2959 samplers->uniforms.push_back(SamplerUniformSp(new de::UniquePtr<SamplerUniform>(uniform)));
2962 m_descriptorSetLayoutBuilder.addArraySamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, numSamplers, VK_SHADER_STAGE_ALL, DE_NULL);
2963 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, numSamplers);
2965 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(samplers)));
2968 void ShaderExecutor::addSamplerUniform (deUint32 bindingLocation,
2969 VkImageView imageView,
2972 de::MovePtr<UnmanagedSamplerUniform> samplerUniform(new UnmanagedSamplerUniform());
2974 const VkDescriptorImageInfo descriptor =
2978 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
2981 samplerUniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
2982 samplerUniform->location = bindingLocation;
2983 samplerUniform->descriptor = descriptor;
2985 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(samplerUniform)));
2987 m_descriptorSetLayoutBuilder.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_ALL, DE_NULL);
2988 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1);
2991 const void* ShaderExecutor::getBufferPtr (const deUint32 bindingLocation) const
2993 std::vector<UniformInfoSp>::const_iterator it = m_uniformInfos.begin();
2994 for (; it != m_uniformInfos.end(); it++)
2996 const UniformInfo* uniformInfo = it->get()->get();
2997 if (uniformInfo->getType() == UniformInfo::UNIFORM_TYPE_BUFFER && uniformInfo->location == bindingLocation)
2999 const BufferUniform* bufferUniform = static_cast<const BufferUniform*>(uniformInfo);
3000 return bufferUniform->alloc->getHostPtr();
3007 void ShaderExecutor::addUniforms (const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc)
3009 if (!m_uniformSetup)
3012 for (std::vector<UniformDataSp>::const_iterator it = m_uniformSetup->uniforms().begin(); it != m_uniformSetup->uniforms().end(); ++it)
3014 const UniformDataBase* uniformData = it->get()->get();
3015 uniformData->setup(*this, vkDevice, vk, queue, queueFamilyIndex, memAlloc);
3019 void ShaderExecutor::uploadUniforms (DescriptorSetUpdateBuilder& descriptorSetUpdateBuilder, VkDescriptorSet descriptorSet)
3021 for (std::vector<UniformInfoSp>::const_iterator it = m_uniformInfos.begin(); it != m_uniformInfos.end(); ++it)
3023 const UniformInfo* uniformInfo = it->get()->get();
3024 UniformInfo::UniformType uniformType = uniformInfo->getType();
3026 if (uniformType == UniformInfo::UNIFORM_TYPE_BUFFER_ARRAY)
3028 const BufferArrayUniform* arrayInfo = static_cast<const BufferArrayUniform*>(uniformInfo);
3029 std::vector<VkDescriptorBufferInfo> descriptors;
3031 for (std::vector<BufferUniformSp>::const_iterator ait = arrayInfo->uniforms.begin(); ait != arrayInfo->uniforms.end(); ++ait)
3033 descriptors.push_back(ait->get()->get()->descriptor);
3036 descriptorSetUpdateBuilder.writeArray(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(uniformInfo->location), uniformInfo->type, (deUint32)descriptors.size(), &descriptors[0]);
3038 else if (uniformType == UniformInfo::UNIFORM_TYPE_SAMPLER_ARRAY)
3040 const SamplerArrayUniform* arrayInfo = static_cast<const SamplerArrayUniform*>(uniformInfo);
3041 std::vector<VkDescriptorImageInfo> descriptors;
3043 for (std::vector<SamplerUniformSp>::const_iterator ait = arrayInfo->uniforms.begin(); ait != arrayInfo->uniforms.end(); ++ait)
3045 descriptors.push_back(ait->get()->get()->descriptor);
3048 descriptorSetUpdateBuilder.writeArray(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(uniformInfo->location), uniformInfo->type, (deUint32)descriptors.size(), &descriptors[0]);
3050 else if (uniformType == UniformInfo::UNIFORM_TYPE_BUFFER)
3052 const BufferUniform* bufferUniform = static_cast<const BufferUniform*>(uniformInfo);
3053 descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(bufferUniform->location), bufferUniform->type, &bufferUniform->descriptor);
3055 else if (uniformType == UniformInfo::UNIFORM_TYPE_SAMPLER)
3057 const SamplerUniform* samplerUniform = static_cast<const SamplerUniform*>(uniformInfo);
3058 descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(samplerUniform->location), samplerUniform->type, &samplerUniform->descriptor);
3060 else if (uniformType == UniformInfo::UNIFORM_TYPE_UNMANAGED_SAMPLER)
3062 const UnmanagedSamplerUniform* samplerUniform = static_cast<const UnmanagedSamplerUniform*>(uniformInfo);
3063 descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(samplerUniform->location), samplerUniform->type, &samplerUniform->descriptor);
3068 void ShaderExecutor::uploadImage (const VkDevice& vkDevice,
3069 const DeviceInterface& vk,
3070 const VkQueue queue,
3071 const deUint32 queueFamilyIndex,
3072 Allocator& memAlloc,
3073 const tcu::TextureFormat& texFormat,
3074 const tcu::IVec3& texSize,
3076 const deUint32 arraySize,
3077 const VkImageAspectFlags aspectMask,
3080 const deUint32 unalignedTextureSize = texSize.x() * texSize.y() * texSize.z() * texFormat.getPixelSize();
3081 const deUint32 alignedTextureSize = deAlign32(unalignedTextureSize, 4u);
3082 deUint32 bufferSize;
3083 Move<VkBuffer> buffer;
3084 de::MovePtr<Allocation> bufferAlloc;
3085 Move<VkCommandPool> cmdPool;
3086 Move<VkCommandBuffer> cmdBuffer;
3087 Move<VkFence> fence;
3088 std::vector<deUint32> levelDataSizes;
3090 // Calculate buffer size
3091 bufferSize = arraySize * alignedTextureSize;
3093 // Create source buffer
3095 const VkBufferCreateInfo bufferParams =
3097 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
3098 DE_NULL, // const void* pNext;
3099 0u, // VkBufferCreateFlags flags;
3100 bufferSize, // VkDeviceSize size;
3101 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
3102 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3103 0u, // deUint32 queueFamilyIndexCount;
3104 DE_NULL, // const deUint32* pQueueFamilyIndices;
3107 buffer = createBuffer(vk, vkDevice, &bufferParams);
3108 bufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
3109 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
3112 // Create command pool and buffer
3113 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
3114 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
3117 fence = createFence(vk, vkDevice);
3119 // Barriers for copying buffer to image
3120 const VkBufferMemoryBarrier preBufferBarrier =
3122 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
3123 DE_NULL, // const void* pNext;
3124 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
3125 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
3126 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
3127 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
3128 *buffer, // VkBuffer buffer;
3129 0u, // VkDeviceSize offset;
3130 bufferSize // VkDeviceSize size;
3133 const VkImageMemoryBarrier preImageBarrier =
3135 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3136 DE_NULL, // const void* pNext;
3137 0u, // VkAccessFlags srcAccessMask;
3138 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
3139 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
3140 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
3141 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
3142 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
3143 destImage, // VkImage image;
3144 { // VkImageSubresourceRange subresourceRange;
3145 aspectMask, // VkImageAspect aspect;
3146 0u, // deUint32 baseMipLevel;
3147 1u, // deUint32 mipLevels;
3148 0u, // deUint32 baseArraySlice;
3149 arraySize // deUint32 arraySize;
3153 const VkImageMemoryBarrier postImageBarrier =
3155 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3156 DE_NULL, // const void* pNext;
3157 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
3158 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
3159 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
3160 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout;
3161 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
3162 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
3163 destImage, // VkImage image;
3164 { // VkImageSubresourceRange subresourceRange;
3165 aspectMask, // VkImageAspect aspect;
3166 0u, // deUint32 baseMipLevel;
3167 1u, // deUint32 mipLevels;
3168 0u, // deUint32 baseArraySlice;
3169 arraySize // deUint32 arraySize;
3173 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
3175 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
3176 DE_NULL, // const void* pNext;
3177 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
3178 (const VkCommandBufferInheritanceInfo*)DE_NULL,
3181 std::vector<VkBufferImageCopy> copyRegions;
3184 deUint32 layerDataOffset = 0;
3186 for (deUint32 layerNdx = 0; layerNdx < arraySize; ++layerNdx)
3188 const VkBufferImageCopy layerRegion =
3190 layerDataOffset, // VkDeviceSize bufferOffset;
3191 (deUint32)texSize.x(), // deUint32 bufferRowLength;
3192 (deUint32)texSize.y(), // deUint32 bufferImageHeight;
3193 { // VkImageSubresourceLayers imageSubresource;
3199 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
3200 { // VkExtent3D imageExtent;
3201 (deUint32)texSize.x(),
3202 (deUint32)texSize.y(),
3203 (deUint32)texSize.z()
3207 copyRegions.push_back(layerRegion);
3208 layerDataOffset += alignedTextureSize;
3212 // Write buffer data
3214 deUint8* destPtr = (deUint8*)bufferAlloc->getHostPtr();
3215 deUint32 levelOffset = 0;
3217 for (deUint32 layerNdx = 0; layerNdx < arraySize; ++layerNdx)
3219 tcu::ConstPixelBufferAccess access (texFormat, texSize, data);
3220 tcu::PixelBufferAccess destAccess (texFormat, texSize, destPtr + levelOffset);
3222 tcu::copy(destAccess, access);
3223 levelOffset += alignedTextureSize;
3227 flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
3229 // Copy buffer to image
3230 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
3231 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
3232 vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data());
3233 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);
3234 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
3236 const VkSubmitInfo submitInfo =
3238 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
3239 DE_NULL, // const void* pNext;
3240 0u, // deUint32 waitSemaphoreCount;
3241 DE_NULL, // const VkSemaphore* pWaitSemaphores;
3243 1u, // deUint32 commandBufferCount;
3244 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
3245 0u, // deUint32 signalSemaphoreCount;
3246 DE_NULL // const VkSemaphore* pSignalSemaphores;
3249 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
3250 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
3253 de::MovePtr<ShaderExecutor::SamplerUniform> ShaderExecutor::createSamplerUniform (const VkDevice& vkDevice,
3254 const DeviceInterface& vk,
3255 const VkQueue queue,
3256 const deUint32 queueFamilyIndex,
3257 Allocator& memAlloc,
3258 deUint32 bindingLocation,
3259 const tcu::Sampler& refSampler,
3260 const tcu::TextureFormat& texFormat,
3261 const tcu::IVec3& texSize,
3262 VkImageType imageType,
3263 VkImageViewType imageViewType,
3266 const VkFormat format = mapTextureFormat(texFormat);
3267 const bool isCube = imageViewType == VK_IMAGE_VIEW_TYPE_CUBE;
3268 const bool isShadowSampler = texFormat == tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
3269 const VkImageCreateFlags imageFlags = isCube ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlags)0;
3270 const deUint32 arraySize = isCube ? 6u : 1u;
3271 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
3272 VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3273 Move<VkImage> vkTexture;
3274 de::MovePtr<Allocation> allocation;
3276 if (isShadowSampler)
3277 imageUsage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
3280 const VkImageCreateInfo imageParams =
3282 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3283 DE_NULL, // const void* pNext;
3284 imageFlags, // VkImageCreateFlags flags;
3285 imageType, // VkImageType imageType;
3286 format, // VkFormat format;
3287 { // VkExtent3D extent;
3288 (deUint32)texSize.x(),
3289 (deUint32)texSize.y(),
3290 (deUint32)texSize.z()
3292 1u, // deUint32 mipLevels;
3293 arraySize, // deUint32 arrayLayers;
3294 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
3295 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
3296 imageUsage, // VkImageUsageFlags usage;
3297 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3298 1u, // deUint32 queueFamilyIndexCount;
3299 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
3300 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
3303 vkTexture = createImage(vk, vkDevice, &imageParams);
3304 allocation = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any);
3305 VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset()));
3307 // Upload texture data
3308 uploadImage(vkDevice, vk, queue, queueFamilyIndex, memAlloc, texFormat, texSize, data, arraySize, aspectMask, *vkTexture);
3311 const VkSamplerCreateInfo samplerParams = mapSampler(refSampler, texFormat);
3312 Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams);
3314 const VkImageViewCreateInfo viewParams =
3316 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
3317 NULL, // const voide* pNexŧ;
3318 0u, // VkImageViewCreateFlags flags;
3319 *vkTexture, // VkImage image;
3320 imageViewType, // VkImageViewType viewType;
3321 format, // VkFormat format;
3323 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
3324 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
3325 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
3326 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
3327 }, // VkComponentMapping components;
3329 aspectMask, // VkImageAspectFlags aspectMask;
3330 0, // deUint32 baseMipLevel;
3331 1, // deUint32 mipLevels;
3332 0, // deUint32 baseArraySlice;
3333 arraySize // deUint32 arraySize;
3334 } // VkImageSubresourceRange subresourceRange;
3337 Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams);
3339 const VkDescriptorImageInfo descriptor =
3341 sampler.get(), // VkSampler sampler;
3342 imageView.get(), // VkImageView imageView;
3343 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout imageLayout;
3346 de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
3347 uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
3348 uniform->descriptor = descriptor;
3349 uniform->location = bindingLocation;
3350 uniform->image = VkImageSp(new Unique<VkImage>(vkTexture));
3351 uniform->imageView = VkImageViewSp(new Unique<VkImageView>(imageView));
3352 uniform->sampler = VkSamplerSp(new Unique<VkSampler>(sampler));
3353 uniform->alloc = AllocationSp(allocation.release());
3358 SamplerUniformData::SamplerUniformData (deUint32 bindingLocation,
3359 deUint32 numSamplers,
3360 const tcu::Sampler& refSampler,
3361 const tcu::TextureFormat& texFormat,
3362 const tcu::IVec3& texSize,
3363 VkImageType imageType,
3364 VkImageViewType imageViewType,
3366 : UniformDataBase (bindingLocation)
3367 , m_numSamplers (numSamplers)
3368 , m_refSampler (refSampler)
3369 , m_texFormat (texFormat)
3370 , m_texSize (texSize)
3371 , m_imageType (imageType)
3372 , m_imageViewType (imageViewType)
3377 SamplerUniformData::~SamplerUniformData (void)
3381 void SamplerUniformData::setup (ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc) const
3383 executor.setupSamplerData(vkDevice, vk, queue, queueFamilyIndex, memAlloc, m_bindingLocation, m_numSamplers, m_refSampler, m_texFormat, m_texSize, m_imageType, m_imageViewType, m_data);