1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and/or associated documentation files (the
10 * "Materials"), to deal in the Materials without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Materials, and to
13 * permit persons to whom the Materials are furnished to do so, subject to
14 * the following conditions:
16 * The above copyright notice(s) and this permission notice shall be included
17 * in all copies or substantial portions of the Materials.
19 * The Materials are Confidential Information as defined by the
20 * Khronos Membership Agreement until designated non-confidential by Khronos,
21 * at which point this condition clause shall be removed.
23 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
33 * \brief Vulkan ShaderExecutor
34 *//*--------------------------------------------------------------------*/
36 #include "vktShaderExecutor.hpp"
41 #include "tcuVector.hpp"
42 #include "tcuTestLog.hpp"
43 #include "tcuFormatUtil.hpp"
44 #include "tcuTextureUtil.hpp"
45 #include "deUniquePtr.hpp"
46 #include "deStringUtil.hpp"
47 #include "deSharedPtr.hpp"
49 #include "vkMemUtil.hpp"
51 #include "vkPlatform.hpp"
52 #include "vkPrograms.hpp"
53 #include "vkStrUtil.hpp"
54 #include "vkRefUtil.hpp"
55 #include "vkTypeUtil.hpp"
56 #include "vkQueryUtil.hpp"
57 #include "vkDeviceUtil.hpp"
58 #include "vkImageUtil.hpp"
60 #include "gluShaderUtil.hpp"
67 namespace shaderexecutor
74 DEFAULT_RENDER_WIDTH = 100,
75 DEFAULT_RENDER_HEIGHT = 100,
80 static VkClearValue getDefaultClearColor (void)
82 return makeClearValueColorF32(0.125f, 0.25f, 0.5f, 1.0f);
85 static void checkSupported (const Context& ctx, glu::ShaderType shaderType)
87 const VkPhysicalDeviceFeatures& features = ctx.getDeviceFeatures();
89 if (shaderType == glu::SHADERTYPE_GEOMETRY && !features.geometryShader)
90 TCU_THROW(NotSupportedError, "Geometry shader type not supported by device");
91 else if (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL && !features.tessellationShader)
92 TCU_THROW(NotSupportedError, "Tessellation shader type not supported by device");
93 else if (shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION && !features.tessellationShader)
94 TCU_THROW(NotSupportedError, "Tessellation shader type not supported by device");
97 static std::string generateEmptyFragmentSource ()
99 std::ostringstream src;
101 src << "#version 310 es\n"
102 "#extension GL_ARB_separate_shader_objects : enable\n"
103 "#extension GL_ARB_shading_language_420pack : enable\n"
104 "layout(location=0) out highp vec4 o_color;\n";
106 src << "void main (void)\n{\n";
107 src << " o_color = vec4(0.0);\n";
113 static std::string generatePassthroughVertexShader (const std::vector<Symbol>& inputs, const char* inputPrefix, const char* outputPrefix)
116 std::ostringstream src;
119 src << "#version 310 es\n"
120 "#extension GL_ARB_separate_shader_objects : enable\n"
121 "#extension GL_ARB_shading_language_420pack : enable\n"
122 "layout(location = " << location << ") in highp vec4 a_position;\n";
124 for (vector<Symbol>::const_iterator input = inputs.begin(); input != inputs.end(); ++input)
127 src << "layout(location = "<< location << ") in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n"
128 << "layout(location = " << location - 1 << ") flat out " << glu::declare(input->varType, outputPrefix + input->name) << ";\n";
131 src << "\nvoid main (void)\n{\n"
132 << " gl_Position = a_position;\n"
133 << " gl_PointSize = 1.0;\n";
135 for (vector<Symbol>::const_iterator input = inputs.begin(); input != inputs.end(); ++input)
136 src << "\t" << outputPrefix << input->name << " = " << inputPrefix << input->name << ";\n";
143 static std::string generateVertexShader (const ShaderSpec& shaderSpec, const std::string& inputPrefix, const std::string& outputPrefix)
145 DE_ASSERT(!inputPrefix.empty() && !outputPrefix.empty());
147 std::ostringstream src;
149 src << "#version 310 es\n"
150 "#extension GL_ARB_separate_shader_objects : enable\n"
151 "#extension GL_ARB_shading_language_420pack : enable\n";
153 if (!shaderSpec.globalDeclarations.empty())
154 src << shaderSpec.globalDeclarations << "\n";
156 src << "layout(location = 0) in highp vec4 a_position;\n";
158 int locationNumber = 1;
159 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber)
160 src << "layout(location = " << locationNumber << ") in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n";
163 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber)
165 DE_ASSERT(output->varType.isBasicType());
167 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
169 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
170 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
171 const glu::VarType intType (intBaseType, glu::PRECISION_HIGHP);
173 src << "layout(location = " << locationNumber << ") flat out " << glu::declare(intType, outputPrefix + output->name) << ";\n";
176 src << "layout(location = " << locationNumber << ") flat out " << glu::declare(output->varType, outputPrefix + output->name) << ";\n";
180 << "void main (void)\n"
182 << " gl_Position = a_position;\n"
183 << " gl_PointSize = 1.0;\n";
185 // Declare & fetch local input variables
186 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input)
187 src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << ";\n";
189 // Declare local output variables
190 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
191 src << "\t" << glu::declare(output->varType, output->name) << ";\n";
193 // Operation - indented to correct level.
195 std::istringstream opSrc (shaderSpec.source);
198 while (std::getline(opSrc, line))
199 src << "\t" << line << "\n";
202 // Assignments to outputs.
203 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
205 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
207 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
208 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
210 src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << output->name << ");\n";
213 src << "\t" << outputPrefix << output->name << " = " << output->name << ";\n";
221 struct FragmentOutputLayout
223 std::vector<const Symbol*> locationSymbols; //! Symbols by location
224 std::map<std::string, int> locationMap; //! Map from symbol name to start location
227 static void generateFragShaderOutputDecl (std::ostream& src, const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& outputPrefix)
229 for (int outNdx = 0; outNdx < (int)shaderSpec.outputs.size(); ++outNdx)
231 const Symbol& output = shaderSpec.outputs[outNdx];
232 const int location = de::lookup(outLocationMap, output.name);
233 const std::string outVarName = outputPrefix + output.name;
234 glu::VariableDeclaration decl (output.varType, outVarName, glu::STORAGE_OUT, glu::INTERPOLATION_LAST, glu::Layout(location));
236 TCU_CHECK_INTERNAL(output.varType.isBasicType());
238 if (useIntOutputs && glu::isDataTypeFloatOrVec(output.varType.getBasicType()))
240 const int vecSize = glu::getDataTypeScalarSize(output.varType.getBasicType());
241 const glu::DataType uintBasicType = vecSize > 1 ? glu::getDataTypeUintVec(vecSize) : glu::TYPE_UINT;
242 const glu::VarType uintType (uintBasicType, glu::PRECISION_HIGHP);
244 decl.varType = uintType;
245 src << decl << ";\n";
247 else if (glu::isDataTypeBoolOrBVec(output.varType.getBasicType()))
249 const int vecSize = glu::getDataTypeScalarSize(output.varType.getBasicType());
250 const glu::DataType intBasicType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
251 const glu::VarType intType (intBasicType, glu::PRECISION_HIGHP);
253 decl.varType = intType;
254 src << decl << ";\n";
256 else if (glu::isDataTypeMatrix(output.varType.getBasicType()))
258 const int vecSize = glu::getDataTypeMatrixNumRows(output.varType.getBasicType());
259 const int numVecs = glu::getDataTypeMatrixNumColumns(output.varType.getBasicType());
260 const glu::DataType uintBasicType = glu::getDataTypeUintVec(vecSize);
261 const glu::VarType uintType (uintBasicType, glu::PRECISION_HIGHP);
263 decl.varType = uintType;
264 for (int vecNdx = 0; vecNdx < numVecs; ++vecNdx)
266 decl.name = outVarName + "_" + de::toString(vecNdx);
267 decl.layout.location = location + vecNdx;
268 src << decl << ";\n";
272 src << decl << ";\n";
276 static void generateFragShaderOutAssign (std::ostream& src, const ShaderSpec& shaderSpec, bool useIntOutputs, const std::string& valuePrefix, const std::string& outputPrefix)
278 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
280 if (useIntOutputs && glu::isDataTypeFloatOrVec(output->varType.getBasicType()))
281 src << " o_" << output->name << " = floatBitsToUint(" << valuePrefix << output->name << ");\n";
282 else if (glu::isDataTypeMatrix(output->varType.getBasicType()))
284 const int numVecs = glu::getDataTypeMatrixNumColumns(output->varType.getBasicType());
286 for (int vecNdx = 0; vecNdx < numVecs; ++vecNdx)
288 src << "\t" << outputPrefix << output->name << "_" << vecNdx << " = floatBitsToUint(" << valuePrefix << output->name << "[" << vecNdx << "]);\n";
290 src << "\t" << outputPrefix << output->name << "_" << vecNdx << " = " << valuePrefix << output->name << "[" << vecNdx << "];\n";
292 else if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
294 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
295 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
297 src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << valuePrefix << output->name << ");\n";
300 src << "\t" << outputPrefix << output->name << " = " << valuePrefix << output->name << ";\n";
304 static std::string generatePassthroughFragmentShader (const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& inputPrefix, const std::string& outputPrefix)
306 std::ostringstream src;
308 src << "#version 310 es\n"
309 "#extension GL_ARB_separate_shader_objects : enable\n"
310 "#extension GL_ARB_shading_language_420pack : enable\n";
312 if (!shaderSpec.globalDeclarations.empty())
313 src << shaderSpec.globalDeclarations << "\n";
315 int locationNumber = 0;
316 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber)
318 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
320 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
321 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
322 const glu::VarType intType (intBaseType, glu::PRECISION_HIGHP);
324 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(intType, inputPrefix + output->name) << ";\n";
327 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(output->varType, inputPrefix + output->name) << ";\n";
330 generateFragShaderOutputDecl(src, shaderSpec, useIntOutputs, outLocationMap, outputPrefix);
332 src << "\nvoid main (void)\n{\n";
334 generateFragShaderOutAssign(src, shaderSpec, useIntOutputs, inputPrefix, outputPrefix);
341 static std::string generateGeometryShader (const ShaderSpec& shaderSpec, const std::string& inputPrefix, const std::string& outputPrefix)
343 DE_ASSERT(!inputPrefix.empty() && !outputPrefix.empty());
345 std::ostringstream src;
347 src << "#version 310 es\n"
348 "#extension GL_EXT_geometry_shader : require\n"
349 "#extension GL_ARB_separate_shader_objects : enable\n"
350 "#extension GL_ARB_shading_language_420pack : enable\n";
352 if (!shaderSpec.globalDeclarations.empty())
353 src << shaderSpec.globalDeclarations << "\n";
355 src << "layout(points) in;\n"
356 << "layout(points, max_vertices = 1) out;\n";
358 int locationNumber = 0;
359 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber)
360 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(input->varType, inputPrefix + input->name) << "[];\n";
363 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber)
365 DE_ASSERT(output->varType.isBasicType());
367 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
369 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
370 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
371 const glu::VarType intType (intBaseType, glu::PRECISION_HIGHP);
373 src << "layout(location = " << locationNumber << ") flat out " << glu::declare(intType, outputPrefix + output->name) << ";\n";
376 src << "layout(location = " << locationNumber << ") flat out " << glu::declare(output->varType, outputPrefix + output->name) << ";\n";
380 << "void main (void)\n"
382 << " gl_Position = gl_in[0].gl_Position;\n\n";
384 // Fetch input variables
385 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input)
386 src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << "[0];\n";
388 // Declare local output variables.
389 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
390 src << "\t" << glu::declare(output->varType, output->name) << ";\n";
394 // Operation - indented to correct level.
396 std::istringstream opSrc (shaderSpec.source);
399 while (std::getline(opSrc, line))
400 src << "\t" << line << "\n";
403 // Assignments to outputs.
404 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
406 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType()))
408 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType());
409 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT;
411 src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << output->name << ");\n";
414 src << "\t" << outputPrefix << output->name << " = " << output->name << ";\n";
417 src << " EmitVertex();\n"
418 << " EndPrimitive();\n"
424 static std::string generateFragmentShader (const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& inputPrefix, const std::string& outputPrefix)
426 std::ostringstream src;
427 src << "#version 310 es\n"
428 "#extension GL_ARB_separate_shader_objects : enable\n"
429 "#extension GL_ARB_shading_language_420pack : enable\n";
430 if (!shaderSpec.globalDeclarations.empty())
431 src << shaderSpec.globalDeclarations << "\n";
433 int locationNumber = 0;
434 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber)
435 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n";
437 generateFragShaderOutputDecl(src, shaderSpec, useIntOutputs, outLocationMap, outputPrefix);
439 src << "\nvoid main (void)\n{\n";
441 // Declare & fetch local input variables
442 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input)
443 src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << ";\n";
445 // Declare output variables
446 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output)
447 src << "\t" << glu::declare(output->varType, output->name) << ";\n";
449 // Operation - indented to correct level.
451 std::istringstream opSrc (shaderSpec.source);
454 while (std::getline(opSrc, line))
455 src << "\t" << line << "\n";
458 generateFragShaderOutAssign(src, shaderSpec, useIntOutputs, "", outputPrefix);
465 // FragmentOutExecutor
467 class FragmentOutExecutor : public ShaderExecutor
470 FragmentOutExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
471 virtual ~FragmentOutExecutor (void);
473 virtual void execute (const Context& ctx,
475 const void* const* inputs,
476 void* const* outputs);
479 const FragmentOutputLayout m_outputLayout;
481 void bindAttributes (const Context& ctx,
484 const void* const* inputs);
486 void addAttribute (const Context& ctx,
488 deUint32 bindingLocation,
490 deUint32 sizePerElement,
492 const void* dataPtr);
493 // reinit render data members
494 virtual void clearRenderData (void);
496 typedef de::SharedPtr<Unique<VkImage> > VkImageSp;
497 typedef de::SharedPtr<Unique<VkImageView> > VkImageViewSp;
498 typedef de::SharedPtr<Unique<VkBuffer> > VkBufferSp;
499 typedef de::SharedPtr<de::UniquePtr<Allocation> > AllocationSp;
501 std::vector<VkVertexInputBindingDescription> m_vertexBindingDescriptions;
502 std::vector<VkVertexInputAttributeDescription> m_vertexAttributeDescriptions;
503 std::vector<VkBufferSp> m_vertexBuffers;
504 std::vector<AllocationSp> m_vertexBufferAllocs;
507 static FragmentOutputLayout computeFragmentOutputLayout (const std::vector<Symbol>& symbols)
509 FragmentOutputLayout ret;
512 for (std::vector<Symbol>::const_iterator it = symbols.begin(); it != symbols.end(); ++it)
514 const int numLocations = glu::getDataTypeNumLocations(it->varType.getBasicType());
516 TCU_CHECK_INTERNAL(!de::contains(ret.locationMap, it->name));
517 de::insert(ret.locationMap, it->name, location);
518 location += numLocations;
520 for (int ndx = 0; ndx < numLocations; ++ndx)
521 ret.locationSymbols.push_back(&*it);
527 FragmentOutExecutor::FragmentOutExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
528 : ShaderExecutor (shaderSpec, shaderType)
529 , m_outputLayout (computeFragmentOutputLayout(m_shaderSpec.outputs))
533 FragmentOutExecutor::~FragmentOutExecutor (void)
537 static std::vector<tcu::Vec2> computeVertexPositions (int numValues, const tcu::IVec2& renderSize)
539 std::vector<tcu::Vec2> positions(numValues);
540 for (int valNdx = 0; valNdx < numValues; valNdx++)
542 const int ix = valNdx % renderSize.x();
543 const int iy = valNdx / renderSize.x();
544 const float fx = -1.0f + 2.0f*((float(ix) + 0.5f) / float(renderSize.x()));
545 const float fy = -1.0f + 2.0f*((float(iy) + 0.5f) / float(renderSize.y()));
547 positions[valNdx] = tcu::Vec2(fx, fy);
553 static tcu::TextureFormat getRenderbufferFormatForOutput (const glu::VarType& outputType, bool useIntOutputs)
555 const tcu::TextureFormat::ChannelOrder channelOrderMap[] =
557 tcu::TextureFormat::R,
558 tcu::TextureFormat::RG,
559 tcu::TextureFormat::RGBA, // No RGB variants available.
560 tcu::TextureFormat::RGBA
563 const glu::DataType basicType = outputType.getBasicType();
564 const int numComps = glu::getDataTypeNumComponents(basicType);
565 tcu::TextureFormat::ChannelType channelType;
567 switch (glu::getDataTypeScalarType(basicType))
569 case glu::TYPE_UINT: channelType = tcu::TextureFormat::UNSIGNED_INT32; break;
570 case glu::TYPE_INT: channelType = tcu::TextureFormat::SIGNED_INT32; break;
571 case glu::TYPE_BOOL: channelType = tcu::TextureFormat::SIGNED_INT32; break;
572 case glu::TYPE_FLOAT: channelType = useIntOutputs ? tcu::TextureFormat::UNSIGNED_INT32 : tcu::TextureFormat::FLOAT; break;
574 throw tcu::InternalError("Invalid output type");
577 DE_ASSERT(de::inRange<int>(numComps, 1, DE_LENGTH_OF_ARRAY(channelOrderMap)));
579 return tcu::TextureFormat(channelOrderMap[numComps-1], channelType);
582 static VkFormat getAttributeFormat (const glu::DataType dataType)
586 case glu::TYPE_FLOAT: return VK_FORMAT_R32_SFLOAT;
587 case glu::TYPE_FLOAT_VEC2: return VK_FORMAT_R32G32_SFLOAT;
588 case glu::TYPE_FLOAT_VEC3: return VK_FORMAT_R32G32B32_SFLOAT;
589 case glu::TYPE_FLOAT_VEC4: return VK_FORMAT_R32G32B32A32_SFLOAT;
591 case glu::TYPE_INT: return VK_FORMAT_R32_SINT;
592 case glu::TYPE_INT_VEC2: return VK_FORMAT_R32G32_SINT;
593 case glu::TYPE_INT_VEC3: return VK_FORMAT_R32G32B32_SINT;
594 case glu::TYPE_INT_VEC4: return VK_FORMAT_R32G32B32A32_SINT;
596 case glu::TYPE_UINT: return VK_FORMAT_R32_UINT;
597 case glu::TYPE_UINT_VEC2: return VK_FORMAT_R32G32_UINT;
598 case glu::TYPE_UINT_VEC3: return VK_FORMAT_R32G32B32_UINT;
599 case glu::TYPE_UINT_VEC4: return VK_FORMAT_R32G32B32A32_UINT;
601 case glu::TYPE_FLOAT_MAT2: return VK_FORMAT_R32G32_SFLOAT;
602 case glu::TYPE_FLOAT_MAT2X3: return VK_FORMAT_R32G32B32_SFLOAT;
603 case glu::TYPE_FLOAT_MAT2X4: return VK_FORMAT_R32G32B32A32_SFLOAT;
604 case glu::TYPE_FLOAT_MAT3X2: return VK_FORMAT_R32G32_SFLOAT;
605 case glu::TYPE_FLOAT_MAT3: return VK_FORMAT_R32G32B32_SFLOAT;
606 case glu::TYPE_FLOAT_MAT3X4: return VK_FORMAT_R32G32B32A32_SFLOAT;
607 case glu::TYPE_FLOAT_MAT4X2: return VK_FORMAT_R32G32_SFLOAT;
608 case glu::TYPE_FLOAT_MAT4X3: return VK_FORMAT_R32G32B32_SFLOAT;
609 case glu::TYPE_FLOAT_MAT4: return VK_FORMAT_R32G32B32A32_SFLOAT;
612 return VK_FORMAT_UNDEFINED;
616 void FragmentOutExecutor::addAttribute (const Context& ctx, Allocator& memAlloc, deUint32 bindingLocation, VkFormat format, deUint32 sizePerElement, deUint32 count, const void* dataPtr)
618 // Add binding specification
619 const deUint32 binding = (deUint32)m_vertexBindingDescriptions.size();
620 const VkVertexInputBindingDescription bindingDescription =
624 VK_VERTEX_INPUT_RATE_VERTEX
627 m_vertexBindingDescriptions.push_back(bindingDescription);
629 // Add location and format specification
630 const VkVertexInputAttributeDescription attributeDescription =
632 bindingLocation, // deUint32 location;
633 binding, // deUint32 binding;
634 format, // VkFormat format;
635 0u, // deUint32 offsetInBytes;
638 m_vertexAttributeDescriptions.push_back(attributeDescription);
640 // Upload data to buffer
641 const VkDevice vkDevice = ctx.getDevice();
642 const DeviceInterface& vk = ctx.getDeviceInterface();
643 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex();
645 const VkDeviceSize inputSize = sizePerElement * count;
646 const VkBufferCreateInfo vertexBufferParams =
648 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
649 DE_NULL, // const void* pNext;
650 0u, // VkBufferCreateFlags flags;
651 inputSize, // VkDeviceSize size;
652 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
653 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
654 1u, // deUint32 queueFamilyCount;
655 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
658 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &vertexBufferParams);
659 de::MovePtr<Allocation> alloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
660 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
662 deMemcpy(alloc->getHostPtr(), dataPtr, (size_t)inputSize);
663 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), inputSize);
665 m_vertexBuffers.push_back(de::SharedPtr<Unique<VkBuffer> >(new Unique<VkBuffer>(buffer)));
666 m_vertexBufferAllocs.push_back(de::SharedPtr<de::UniquePtr<Allocation> >(new de::UniquePtr<Allocation>(alloc)));
669 void FragmentOutExecutor::bindAttributes (const Context& ctx, Allocator& memAlloc, int numValues, const void* const* inputs)
672 for (int inputNdx = 0; inputNdx < (int)m_shaderSpec.inputs.size(); inputNdx++)
674 const Symbol& symbol = m_shaderSpec.inputs[inputNdx];
675 const void* ptr = inputs[inputNdx];
676 const glu::DataType basicType = symbol.varType.getBasicType();
677 const int vecSize = glu::getDataTypeScalarSize(basicType);
678 const VkFormat format = getAttributeFormat(basicType);
680 int numAttrsToAdd = 1;
682 if (glu::isDataTypeFloatOrVec(basicType))
683 elementSize = sizeof(float);
684 else if (glu::isDataTypeIntOrIVec(basicType))
685 elementSize = sizeof(int);
686 else if (glu::isDataTypeUintOrUVec(basicType))
687 elementSize = sizeof(deUint32);
688 else if (glu::isDataTypeMatrix(basicType))
690 int numRows = glu::getDataTypeMatrixNumRows(basicType);
691 int numCols = glu::getDataTypeMatrixNumColumns(basicType);
693 elementSize = numRows * numCols * (int)sizeof(float);
694 numAttrsToAdd = numCols;
699 // add attributes, in case of matrix every column is binded as an attribute
700 for (int attrNdx = 0; attrNdx < numAttrsToAdd; attrNdx++)
702 addAttribute(ctx, memAlloc, (deUint32)m_vertexBindingDescriptions.size(), format, elementSize * vecSize, numValues, ptr);
707 void FragmentOutExecutor::clearRenderData (void)
709 m_vertexBindingDescriptions.clear();
710 m_vertexAttributeDescriptions.clear();
711 m_vertexBuffers.clear();
712 m_vertexBufferAllocs.clear();
715 void FragmentOutExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs)
717 checkSupported(ctx, m_shaderType);
719 const VkDevice vkDevice = ctx.getDevice();
720 const DeviceInterface& vk = ctx.getDeviceInterface();
721 const VkQueue queue = ctx.getUniversalQueue();
722 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex();
723 Allocator& memAlloc = ctx.getDefaultAllocator();
725 const deUint32 renderSizeX = de::min(static_cast<deUint32>(DEFAULT_RENDER_WIDTH), (deUint32)numValues);
726 const deUint32 renderSizeY = ((deUint32)numValues / renderSizeX) + (((deUint32)numValues % renderSizeX != 0) ? 1u : 0u);
727 const tcu::UVec2 renderSize (renderSizeX, renderSizeY);
728 std::vector<tcu::Vec2> positions;
730 VkFormat colorFormat = VK_FORMAT_R32G32B32A32_SFLOAT;
732 const bool useGeometryShader = m_shaderType == glu::SHADERTYPE_GEOMETRY;
734 std::vector<VkImageSp> colorImages;
735 std::vector<VkImageMemoryBarrier> colorImagePreRenderBarriers;
736 std::vector<VkImageMemoryBarrier> colorImagePostRenderBarriers;
737 std::vector<AllocationSp> colorImageAllocs;
738 std::vector<VkAttachmentDescription> attachments;
739 std::vector<VkClearValue> attachmentClearValues;
740 std::vector<VkImageViewSp> colorImageViews;
742 std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentStates;
743 std::vector<VkAttachmentReference> colorAttachmentReferences;
745 Move<VkRenderPass> renderPass;
746 Move<VkFramebuffer> framebuffer;
747 Move<VkPipelineLayout> pipelineLayout;
748 Move<VkPipeline> graphicsPipeline;
750 Move<VkShaderModule> vertexShaderModule;
751 Move<VkShaderModule> geometryShaderModule;
752 Move<VkShaderModule> fragmentShaderModule;
754 Move<VkCommandPool> cmdPool;
755 Move<VkCommandBuffer> cmdBuffer;
759 Move<VkDescriptorPool> descriptorPool;
760 Move<VkDescriptorSetLayout> descriptorSetLayout;
761 Move<VkDescriptorSet> descriptorSet;
765 // Compute positions - 1px points are used to drive fragment shading.
766 positions = computeVertexPositions(numValues, renderSize.cast<int>());
769 addAttribute(ctx, memAlloc, 0u, VK_FORMAT_R32G32_SFLOAT, sizeof(tcu::Vec2), (deUint32)positions.size(), &positions[0]);
770 bindAttributes(ctx, memAlloc, numValues, inputs);
772 // Create color images
774 const VkImageCreateInfo colorImageParams =
776 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
777 DE_NULL, // const void* pNext;
778 0u, // VkImageCreateFlags flags;
779 VK_IMAGE_TYPE_2D, // VkImageType imageType;
780 colorFormat, // VkFormat format;
781 { renderSize.x(), renderSize.y(), 1u }, // VkExtent3D extent;
782 1u, // deUint32 mipLevels;
783 1u, // deUint32 arraySize;
784 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
785 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
786 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
787 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
788 1u, // deUint32 queueFamilyCount;
789 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
790 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
793 const VkAttachmentDescription colorAttachmentDescription =
795 0u, // VkAttachmentDescriptorFlags flags;
796 colorFormat, // VkFormat format;
797 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
798 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
799 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
800 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
801 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
802 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
803 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
806 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
808 VK_FALSE, // VkBool32 blendEnable;
809 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
810 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
811 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
812 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
813 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destAlphaBlendFactor;
814 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
815 (VK_COLOR_COMPONENT_R_BIT |
816 VK_COLOR_COMPONENT_G_BIT |
817 VK_COLOR_COMPONENT_B_BIT |
818 VK_COLOR_COMPONENT_A_BIT) // VkColorComponentFlags colorWriteMask;
821 for (int outNdx = 0; outNdx < (int)m_outputLayout.locationSymbols.size(); ++outNdx)
823 Move<VkImage> colorImage = createImage(vk, vkDevice, &colorImageParams);
824 colorImages.push_back(de::SharedPtr<Unique<VkImage> >(new Unique<VkImage>(colorImage)));
825 attachmentClearValues.push_back(getDefaultClearColor());
827 // Allocate and bind color image memory
829 de::MovePtr<Allocation> colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *((const VkImage*) colorImages.back().get())), MemoryRequirement::Any);
830 VK_CHECK(vk.bindImageMemory(vkDevice, colorImages.back().get()->get(), colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
831 colorImageAllocs.push_back(de::SharedPtr<de::UniquePtr<Allocation> >(new de::UniquePtr<Allocation>(colorImageAlloc)));
833 attachments.push_back(colorAttachmentDescription);
834 colorBlendAttachmentStates.push_back(colorBlendAttachmentState);
836 const VkAttachmentReference colorAttachmentReference = {
837 (deUint32) (colorImages.size() - 1), // deUint32 attachment;
838 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
841 colorAttachmentReferences.push_back(colorAttachmentReference);
844 // Create color attachment view
846 const VkImageViewCreateInfo colorImageViewParams =
848 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
849 DE_NULL, // const void* pNext;
850 0u, // VkImageViewCreateFlags flags;
851 colorImages.back().get()->get(), // VkImage image;
852 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
853 colorFormat, // VkFormat format;
855 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
856 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
857 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
858 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
859 }, // VkComponentMapping components;
861 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
862 0u, // deUint32 baseMipLevel;
863 1u, // deUint32 mipLevels;
864 0u, // deUint32 baseArraySlice;
865 1u // deUint32 arraySize;
866 } // VkImageSubresourceRange subresourceRange;
869 Move<VkImageView> colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
870 colorImageViews.push_back(de::SharedPtr<Unique<VkImageView> >(new Unique<VkImageView>(colorImageView)));
872 const VkImageMemoryBarrier colorImagePreRenderBarrier =
874 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
877 (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
878 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), // dstAccessMask
879 VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
880 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
881 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
882 VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex
883 colorImages.back().get()->get(), // image
885 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
888 0u, // baseArrayLayer
890 } // subresourceRange
892 colorImagePreRenderBarriers.push_back(colorImagePreRenderBarrier);
894 const VkImageMemoryBarrier colorImagePostRenderBarrier =
896 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
898 (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
899 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), // srcAccessMask
900 VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask
901 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout
902 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
903 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
904 VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex
905 colorImages.back().get()->get(), // image
907 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
910 0u, // baseArrayLayer
912 } // subresourceRange
914 colorImagePostRenderBarriers.push_back(colorImagePostRenderBarrier);
919 // Create render pass
921 const VkSubpassDescription subpassDescription =
923 0u, // VkSubpassDescriptionFlags flags;
924 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
925 0u, // deUint32 inputCount;
926 DE_NULL, // const VkAttachmentReference* pInputAttachments;
927 (deUint32)colorImages.size(), // deUint32 colorCount;
928 &colorAttachmentReferences[0], // const VkAttachmentReference* colorAttachments;
929 DE_NULL, // const VkAttachmentReference* resolveAttachments;
930 DE_NULL, // VkAttachmentReference depthStencilAttachment;
931 0u, // deUint32 preserveCount;
932 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
935 const VkRenderPassCreateInfo renderPassParams =
937 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
938 DE_NULL, // const void* pNext;
939 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
940 (deUint32)attachments.size(), // deUint32 attachmentCount;
941 &attachments[0], // const VkAttachmentDescription* pAttachments;
942 1u, // deUint32 subpassCount;
943 &subpassDescription, // const VkSubpassDescription* pSubpasses;
944 0u, // deUint32 dependencyCount;
945 DE_NULL // const VkSubpassDependency* pDependencies;
948 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
951 // Create framebuffer
953 std::vector<VkImageView> views(colorImageViews.size());
954 for (size_t i = 0; i < colorImageViews.size(); i++)
956 views[i] = colorImageViews[i].get()->get();
959 const VkFramebufferCreateInfo framebufferParams =
961 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
962 DE_NULL, // const void* pNext;
963 0u, // VkFramebufferCreateFlags flags;
964 *renderPass, // VkRenderPass renderPass;
965 (deUint32)views.size(), // deUint32 attachmentCount;
966 &views[0], // const VkImageView* pAttachments;
967 (deUint32)renderSize.x(), // deUint32 width;
968 (deUint32)renderSize.y(), // deUint32 height;
969 1u // deUint32 layers;
972 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
975 // Create descriptors
977 addUniforms(vkDevice, vk, queueFamilyIndex, memAlloc);
979 descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
980 descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
982 const VkDescriptorSetAllocateInfo allocInfo =
984 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
988 &*descriptorSetLayout
991 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
993 // Update descriptors
995 vk::DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
997 uploadUniforms(descriptorSetUpdateBuilder, *descriptorSet);
999 descriptorSetUpdateBuilder.update(vk, vkDevice);
1003 // Create pipeline layout
1005 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1007 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1008 DE_NULL, // const void* pNext;
1009 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
1010 1, // deUint32 descriptorSetCount;
1011 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
1012 0u, // deUint32 pushConstantRangeCount;
1013 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1016 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1021 vertexShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("vert"), 0);
1022 fragmentShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("frag"), 0);
1024 if (useGeometryShader)
1026 geometryShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("geom"), 0);
1032 std::vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
1034 const VkPipelineShaderStageCreateInfo vertexShaderStageParams =
1036 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1037 DE_NULL, // const void* pNext;
1038 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
1039 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
1040 *vertexShaderModule, // VkShaderModule module;
1041 "main", // const char* pName;
1042 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1045 const VkPipelineShaderStageCreateInfo fragmentShaderStageParams =
1047 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1048 DE_NULL, // const void* pNext;
1049 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
1050 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
1051 *fragmentShaderModule, // VkShaderModule module;
1052 "main", // const char* pName;
1053 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1056 shaderStageParams.push_back(vertexShaderStageParams);
1057 shaderStageParams.push_back(fragmentShaderStageParams);
1059 if (useGeometryShader)
1061 const VkPipelineShaderStageCreateInfo geometryShaderStageParams =
1063 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1064 DE_NULL, // const void* pNext;
1065 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
1066 VK_SHADER_STAGE_GEOMETRY_BIT, // VkShaderStageFlagBits stage;
1067 *geometryShaderModule, // VkShaderModule module;
1068 "main", // VkShader shader;
1069 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
1072 shaderStageParams.push_back(geometryShaderStageParams);
1075 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1077 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1078 DE_NULL, // const void* pNext;
1079 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
1080 (deUint32)m_vertexBindingDescriptions.size(), // deUint32 bindingCount;
1081 &m_vertexBindingDescriptions[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1082 (deUint32)m_vertexAttributeDescriptions.size(), // deUint32 attributeCount;
1083 &m_vertexAttributeDescriptions[0], // const VkVertexInputAttributeDescription* pvertexAttributeDescriptions;
1086 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
1088 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1089 DE_NULL, // const void* pNext;
1090 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
1091 VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // VkPrimitiveTopology topology;
1092 DE_FALSE // VkBool32 primitiveRestartEnable;
1095 const VkViewport viewport =
1097 0.0f, // float originX;
1098 0.0f, // float originY;
1099 (float)renderSize.x(), // float width;
1100 (float)renderSize.y(), // float height;
1101 0.0f, // float minDepth;
1102 1.0f // float maxDepth;
1105 const VkRect2D scissor =
1110 }, // VkOffset2D offset;
1112 renderSize.x(), // deUint32 width;
1113 renderSize.y(), // deUint32 height;
1114 }, // VkExtent2D extent;
1117 const VkPipelineViewportStateCreateInfo viewportStateParams =
1119 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
1120 DE_NULL, // const void* pNext;
1121 0u, // VkPipelineViewportStateCreateFlags flags;
1122 1u, // deUint32 viewportCount;
1123 &viewport, // const VkViewport* pViewports;
1124 1u, // deUint32 scissorsCount;
1125 &scissor // const VkRect2D* pScissors;
1128 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
1130 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1131 DE_NULL, // const void* pNext;
1132 (VkPipelineRasterizationStateCreateFlags)0u, //VkPipelineRasterizationStateCreateFlags flags;
1133 VK_FALSE, // VkBool32 depthClipEnable;
1134 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
1135 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
1136 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
1137 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
1138 VK_FALSE, // VkBool32 depthBiasEnable;
1139 0.0f, // float depthBias;
1140 0.0f, // float depthBiasClamp;
1141 0.0f, // float slopeScaledDepthBias;
1142 1.0f // float lineWidth;
1145 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1147 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1148 DE_NULL, // const void* pNext;
1149 0u, // VkPipelineMultisampleStateCreateFlags flags;
1150 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
1151 VK_FALSE, // VkBool32 sampleShadingEnable;
1152 0.0f, // float minSampleShading;
1153 DE_NULL, // const VkSampleMask* pSampleMask;
1154 VK_FALSE, // VkBool32 alphaToCoverageEnable;
1155 VK_FALSE // VkBool32 alphaToOneEnable;
1158 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1160 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1161 DE_NULL, // const void* pNext;
1162 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
1163 VK_FALSE, // VkBool32 logicOpEnable;
1164 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1165 (deUint32)colorBlendAttachmentStates.size(), // deUint32 attachmentCount;
1166 &colorBlendAttachmentStates[0], // const VkPipelineColorBlendAttachmentState* pAttachments;
1167 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConst[4];
1170 const VkPipelineDynamicStateCreateInfo dynamicStateInfo =
1172 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
1173 DE_NULL, // const void* pNext;
1174 (VkPipelineDynamicStateCreateFlags)0, // VkPipelineDynamicStateCreateFlags flags;
1175 0u, // deUint32 dynamicStateCount;
1176 DE_NULL // const VkDynamicState* pDynamicStates;
1179 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1181 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1182 DE_NULL, // const void* pNext;
1183 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
1184 (deUint32)shaderStageParams.size(), // deUint32 stageCount;
1185 &shaderStageParams[0], // const VkPipelineShaderStageCreateInfo* pStages;
1186 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1187 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1188 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1189 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
1190 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
1191 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1192 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1193 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1194 &dynamicStateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
1195 *pipelineLayout, // VkPipelineLayout layout;
1196 *renderPass, // VkRenderPass renderPass;
1197 0u, // deUint32 subpass;
1198 0u, // VkPipeline basePipelineHandle;
1199 0u // deInt32 basePipelineIndex;
1202 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
1205 // Create command pool
1207 const VkCommandPoolCreateInfo cmdPoolParams =
1209 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
1210 DE_NULL, // const void* pNext;
1211 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
1212 queueFamilyIndex, // deUint32 queueFamilyIndex;
1215 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1218 // Create command buffer
1220 const VkCommandBufferAllocateInfo cmdBufferParams =
1222 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1223 DE_NULL, // const void* pNext;
1224 *cmdPool, // VkCmdPool cmdPool;
1225 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1226 1 // deUint32 bufferCount;
1229 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1231 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1232 DE_NULL, // const void* pNext;
1233 0u, // VkCmdBufferOptimizeFlags flags;
1234 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1237 const VkRenderPassBeginInfo renderPassBeginInfo =
1239 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1240 DE_NULL, // const void* pNext;
1241 *renderPass, // VkRenderPass renderPass;
1242 *framebuffer, // VkFramebuffer framebuffer;
1243 { { 0, 0 }, { renderSize.x(), renderSize.y() } }, // VkRect2D renderArea;
1244 (deUint32)attachmentClearValues.size(), // deUint32 attachmentCount;
1245 &attachmentClearValues[0] // const VkClearValue* pAttachmentClearValues;
1248 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
1250 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1253 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
1254 0, (const VkMemoryBarrier*)DE_NULL,
1255 0, (const VkBufferMemoryBarrier*)DE_NULL,
1256 (deUint32)colorImagePreRenderBarriers.size(), colorImagePreRenderBarriers.empty() ? DE_NULL : &colorImagePreRenderBarriers[0]);
1257 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1259 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
1260 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
1262 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
1264 std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
1266 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
1267 for (size_t i = 0; i < numberOfVertexAttributes; i++)
1269 buffers[i] = m_vertexBuffers[i].get()->get();
1272 vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
1273 vk.cmdDraw(*cmdBuffer, (deUint32)positions.size(), 1u, 0u, 0u);
1275 vk.cmdEndRenderPass(*cmdBuffer);
1276 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
1277 0, (const VkMemoryBarrier*)DE_NULL,
1278 0, (const VkBufferMemoryBarrier*)DE_NULL,
1279 (deUint32)colorImagePostRenderBarriers.size(), colorImagePostRenderBarriers.empty() ? DE_NULL : &colorImagePostRenderBarriers[0]);
1281 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1286 const VkFenceCreateInfo fenceParams =
1288 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
1289 DE_NULL, // const void* pNext;
1290 0u // VkFenceCreateFlags flags;
1293 fence = createFence(vk, vkDevice, &fenceParams);
1299 const VkSubmitInfo submitInfo =
1301 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
1303 0u, // waitSemaphoreCount
1304 DE_NULL, // pWaitSemaphores
1305 (const VkPipelineStageFlags*)DE_NULL,
1306 1u, // commandBufferCount
1307 &cmdBuffer.get(), // pCommandBuffers
1308 0u, // signalSemaphoreCount
1309 DE_NULL // pSignalSemaphores
1312 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1313 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1314 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), DE_TRUE, ~(0ull) /* infinity*/));
1317 // Read back result and output
1319 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(4 * sizeof(deUint32) * renderSize.x() * renderSize.y());
1320 const VkBufferCreateInfo readImageBufferParams =
1322 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1323 DE_NULL, // const void* pNext;
1324 0u, // VkBufferCreateFlags flags;
1325 imageSizeBytes, // VkDeviceSize size;
1326 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
1327 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1328 1u, // deUint32 queueFamilyCount;
1329 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1332 // constants for image copy
1334 const VkCommandPoolCreateInfo cmdPoolParams =
1336 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
1337 DE_NULL, // const void* pNext;
1338 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
1339 queueFamilyIndex // deUint32 queueFamilyIndex;
1342 Move<VkCommandPool> copyCmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1344 const VkCommandBufferAllocateInfo cmdBufferParams =
1346 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1347 DE_NULL, // const void* pNext;
1348 *copyCmdPool, // VkCmdPool cmdPool;
1349 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1350 1u // deUint32 bufferCount;
1353 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1355 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1356 DE_NULL, // const void* pNext;
1357 0u, // VkCmdBufferOptimizeFlags flags;
1358 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1361 const VkBufferImageCopy copyParams =
1363 0u, // VkDeviceSize bufferOffset;
1364 (deUint32)renderSize.x(), // deUint32 bufferRowLength;
1365 (deUint32)renderSize.y(), // deUint32 bufferImageHeight;
1367 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
1368 0u, // deUint32 mipLevel;
1369 0u, // deUint32 arraySlice;
1370 1u, // deUint32 arraySize;
1371 }, // VkImageSubresource imageSubresource;
1372 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
1373 { renderSize.x(), renderSize.y(), 1u } // VkExtent3D imageExtent;
1376 // Read back pixels.
1377 for (int outNdx = 0; outNdx < (int)m_shaderSpec.outputs.size(); ++outNdx)
1379 const Symbol& output = m_shaderSpec.outputs[outNdx];
1380 const int outSize = output.varType.getScalarSize();
1381 const int outVecSize = glu::getDataTypeNumComponents(output.varType.getBasicType());
1382 const int outNumLocs = glu::getDataTypeNumLocations(output.varType.getBasicType());
1383 deUint32* dstPtrBase = static_cast<deUint32*>(outputs[outNdx]);
1384 const int outLocation = de::lookup(m_outputLayout.locationMap, output.name);
1386 for (int locNdx = 0; locNdx < outNumLocs; ++locNdx)
1388 tcu::TextureLevel tmpBuf;
1389 const tcu::TextureFormat format = getRenderbufferFormatForOutput(output.varType, false);
1390 const tcu::TextureFormat readFormat (tcu::TextureFormat::RGBA, format.type);
1391 const Unique<VkBuffer> readImageBuffer(createBuffer(vk, vkDevice, &readImageBufferParams));
1392 const de::UniquePtr<Allocation> readImageBufferMemory(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
1394 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
1396 // Copy image to buffer
1399 Move<VkCommandBuffer> copyCmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
1401 const VkSubmitInfo submitInfo =
1403 VK_STRUCTURE_TYPE_SUBMIT_INFO,
1406 (const VkSemaphore*)DE_NULL,
1407 (const VkPipelineStageFlags*)DE_NULL,
1409 ©CmdBuffer.get(),
1411 (const VkSemaphore*)DE_NULL,
1414 VK_CHECK(vk.beginCommandBuffer(*copyCmdBuffer, &cmdBufferBeginInfo));
1415 vk.cmdCopyImageToBuffer(*copyCmdBuffer, colorImages[outLocation + locNdx].get()->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params);
1416 VK_CHECK(vk.endCommandBuffer(*copyCmdBuffer));
1418 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1419 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1420 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
1423 const VkMappedMemoryRange range =
1425 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
1426 DE_NULL, // const void* pNext;
1427 readImageBufferMemory->getMemory(), // VkDeviceMemory mem;
1428 0, // VkDeviceSize offset;
1429 imageSizeBytes, // VkDeviceSize size;
1432 VK_CHECK(vk.invalidateMappedMemoryRanges(vkDevice, 1u, &range));
1434 tmpBuf.setStorage(readFormat, renderSize.x(), renderSize.y());
1436 const tcu::TextureFormat resultFormat(tcu::TextureFormat::RGBA, format.type);
1437 const tcu::ConstPixelBufferAccess resultAccess(resultFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr());
1439 tcu::copy(tmpBuf.getAccess(), resultAccess);
1441 if (outSize == 4 && outNumLocs == 1)
1442 deMemcpy(dstPtrBase, tmpBuf.getAccess().getDataPtr(), numValues * outVecSize * sizeof(deUint32));
1445 for (int valNdx = 0; valNdx < numValues; valNdx++)
1447 const deUint32* srcPtr = (const deUint32*)tmpBuf.getAccess().getDataPtr() + valNdx * 4;
1448 deUint32* dstPtr = &dstPtrBase[outSize * valNdx + outVecSize * locNdx];
1449 deMemcpy(dstPtr, srcPtr, outVecSize * sizeof(deUint32));
1457 // VertexShaderExecutor
1459 class VertexShaderExecutor : public FragmentOutExecutor
1462 VertexShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1463 virtual ~VertexShaderExecutor (void);
1465 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst;}
1467 virtual void setShaderSources (SourceCollections& programCollection) const;
1471 VertexShaderExecutor::VertexShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1472 : FragmentOutExecutor (shaderSpec, shaderType)
1476 VertexShaderExecutor::~VertexShaderExecutor (void)
1480 void VertexShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1482 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShader(m_shaderSpec, "a_", "vtx_out_"));
1483 /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1484 programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(m_shaderSpec, false, m_outputLayout.locationMap, "vtx_out_", "o_"));
1487 // GeometryShaderExecutor
1489 class GeometryShaderExecutor : public FragmentOutExecutor
1492 GeometryShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1493 virtual ~GeometryShaderExecutor (void);
1495 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst; }
1497 virtual void setShaderSources (SourceCollections& programCollection) const;
1501 GeometryShaderExecutor::GeometryShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1502 : FragmentOutExecutor (shaderSpec, shaderType)
1506 GeometryShaderExecutor::~GeometryShaderExecutor (void)
1510 void GeometryShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1512 programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(m_shaderSpec.inputs, "a_", "vtx_out_"));
1514 programCollection.glslSources.add("geom") << glu::GeometrySource(generateGeometryShader(m_shaderSpec, "vtx_out_", "geom_out_"));
1516 /* \todo [2015-09-18 rsipka] set useIntOutputs parameter if needed. */
1517 programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(m_shaderSpec, false, m_outputLayout.locationMap, "geom_out_", "o_"));
1521 // FragmentShaderExecutor
1523 class FragmentShaderExecutor : public FragmentOutExecutor
1526 FragmentShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1527 virtual ~FragmentShaderExecutor (void);
1529 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst; }
1531 virtual void setShaderSources (SourceCollections& programCollection) const;
1535 FragmentShaderExecutor::FragmentShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1536 : FragmentOutExecutor (shaderSpec, shaderType)
1540 FragmentShaderExecutor::~FragmentShaderExecutor (void)
1544 void FragmentShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1546 programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(m_shaderSpec.inputs, "a_", "vtx_out_"));
1547 /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1548 programCollection.glslSources.add("frag") << glu::FragmentSource(generateFragmentShader(m_shaderSpec, false, m_outputLayout.locationMap, "vtx_out_", "o_"));
1551 // Shared utilities for compute and tess executors
1553 static deUint32 getVecStd430ByteAlignment (glu::DataType type)
1555 switch (glu::getDataTypeScalarSize(type))
1567 class BufferIoExecutor : public ShaderExecutor
1570 BufferIoExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1571 virtual ~BufferIoExecutor (void);
1573 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst; }
1578 INPUT_BUFFER_BINDING = 0,
1579 OUTPUT_BUFFER_BINDING = 1,
1582 void initBuffers (const Context& ctx, int numValues);
1583 VkBuffer getInputBuffer (void) const { return *m_inputBuffer; }
1584 VkBuffer getOutputBuffer (void) const { return *m_outputBuffer; }
1585 deUint32 getInputStride (void) const { return getLayoutStride(m_inputLayout); }
1586 deUint32 getOutputStride (void) const { return getLayoutStride(m_outputLayout); }
1588 void uploadInputBuffer (const Context& ctx, const void* const* inputPtrs, int numValues);
1589 void readOutputBuffer (const Context& ctx, void* const* outputPtrs, int numValues);
1591 static void declareBufferBlocks (std::ostream& src, const ShaderSpec& spec);
1592 static void generateExecBufferIo(std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName);
1595 Move<VkBuffer> m_inputBuffer;
1596 Move<VkBuffer> m_outputBuffer;
1603 deUint32 matrixStride;
1605 VarLayout (void) : offset(0), stride(0), matrixStride(0) {}
1608 static void computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout);
1609 static deUint32 getLayoutStride (const vector<VarLayout>& layout);
1611 static void copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1612 static void copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1614 de::MovePtr<Allocation> m_inputAlloc;
1615 de::MovePtr<Allocation> m_outputAlloc;
1617 vector<VarLayout> m_inputLayout;
1618 vector<VarLayout> m_outputLayout;
1621 BufferIoExecutor::BufferIoExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1622 : ShaderExecutor (shaderSpec, shaderType)
1624 computeVarLayout(m_shaderSpec.inputs, &m_inputLayout);
1625 computeVarLayout(m_shaderSpec.outputs, &m_outputLayout);
1628 BufferIoExecutor::~BufferIoExecutor (void)
1632 inline deUint32 BufferIoExecutor::getLayoutStride (const vector<VarLayout>& layout)
1634 return layout.empty() ? 0 : layout[0].stride;
1637 void BufferIoExecutor::computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout)
1639 deUint32 maxAlignment = 0;
1640 deUint32 curOffset = 0;
1642 DE_ASSERT(layout != DE_NULL);
1643 DE_ASSERT(layout->empty());
1644 layout->resize(symbols.size());
1646 for (size_t varNdx = 0; varNdx < symbols.size(); varNdx++)
1648 const Symbol& symbol = symbols[varNdx];
1649 const glu::DataType basicType = symbol.varType.getBasicType();
1650 VarLayout& layoutEntry = (*layout)[varNdx];
1652 if (glu::isDataTypeScalarOrVector(basicType))
1654 const deUint32 alignment = getVecStd430ByteAlignment(basicType);
1655 const deUint32 size = (deUint32)glu::getDataTypeScalarSize(basicType) * (int)sizeof(deUint32);
1657 curOffset = (deUint32)deAlign32((int)curOffset, (int)alignment);
1658 maxAlignment = de::max(maxAlignment, alignment);
1660 layoutEntry.offset = curOffset;
1661 layoutEntry.matrixStride = 0;
1665 else if (glu::isDataTypeMatrix(basicType))
1667 const int numVecs = glu::getDataTypeMatrixNumColumns(basicType);
1668 const glu::DataType vecType = glu::getDataTypeFloatVec(glu::getDataTypeMatrixNumRows(basicType));
1669 const deUint32 vecAlignment = getVecStd430ByteAlignment(vecType);
1671 curOffset = (deUint32)deAlign32((int)curOffset, (int)vecAlignment);
1672 maxAlignment = de::max(maxAlignment, vecAlignment);
1674 layoutEntry.offset = curOffset;
1675 layoutEntry.matrixStride = vecAlignment;
1677 curOffset += vecAlignment*numVecs;
1684 const deUint32 totalSize = (deUint32)deAlign32(curOffset, maxAlignment);
1686 for (vector<VarLayout>::iterator varIter = layout->begin(); varIter != layout->end(); ++varIter)
1687 varIter->stride = totalSize;
1691 void BufferIoExecutor::declareBufferBlocks (std::ostream& src, const ShaderSpec& spec)
1694 if (!spec.inputs.empty())
1696 glu::StructType inputStruct("Inputs");
1697 for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1698 inputStruct.addMember(symIter->name.c_str(), symIter->varType);
1699 src << glu::declare(&inputStruct) << ";\n";
1704 glu::StructType outputStruct("Outputs");
1705 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1706 outputStruct.addMember(symIter->name.c_str(), symIter->varType);
1707 src << glu::declare(&outputStruct) << ";\n";
1712 if (!spec.inputs.empty())
1714 src << "layout(set = 0, binding = " << int(INPUT_BUFFER_BINDING) << ", std430) buffer InBuffer\n"
1716 << " Inputs inputs[];\n"
1720 src << "layout(set = 0, binding = " << int(OUTPUT_BUFFER_BINDING) << ", std430) buffer OutBuffer\n"
1722 << " Outputs outputs[];\n"
1727 void BufferIoExecutor::generateExecBufferIo (std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName)
1729 for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1730 src << "\t" << glu::declare(symIter->varType, symIter->name) << " = inputs[" << invocationNdxName << "]." << symIter->name << ";\n";
1732 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1733 src << "\t" << glu::declare(symIter->varType, symIter->name) << ";\n";
1738 std::istringstream opSrc (spec.source);
1741 while (std::getline(opSrc, line))
1742 src << "\t" << line << "\n";
1746 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1747 src << "\toutputs[" << invocationNdxName << "]." << symIter->name << " = " << symIter->name << ";\n";
1750 void BufferIoExecutor::copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1752 if (varType.isBasicType())
1754 const glu::DataType basicType = varType.getBasicType();
1755 const bool isMatrix = glu::isDataTypeMatrix(basicType);
1756 const int scalarSize = glu::getDataTypeScalarSize(basicType);
1757 const int numVecs = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1758 const int numComps = scalarSize / numVecs;
1760 for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1762 for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1764 const int srcOffset = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1765 const int dstOffset = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1766 const deUint8* srcPtr = (const deUint8*)srcBasePtr + srcOffset;
1767 deUint8* dstPtr = (deUint8*)dstBasePtr + dstOffset;
1769 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1774 throw tcu::InternalError("Unsupported type");
1777 void BufferIoExecutor::copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1779 if (varType.isBasicType())
1781 const glu::DataType basicType = varType.getBasicType();
1782 const bool isMatrix = glu::isDataTypeMatrix(basicType);
1783 const int scalarSize = glu::getDataTypeScalarSize(basicType);
1784 const int numVecs = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1785 const int numComps = scalarSize / numVecs;
1787 for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1789 for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1791 const int srcOffset = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1792 const int dstOffset = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1793 const deUint8* srcPtr = (const deUint8*)srcBasePtr + srcOffset;
1794 deUint8* dstPtr = (deUint8*)dstBasePtr + dstOffset;
1796 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1801 throw tcu::InternalError("Unsupported type");
1804 void BufferIoExecutor::uploadInputBuffer (const Context& ctx, const void* const* inputPtrs, int numValues)
1806 const VkDevice vkDevice = ctx.getDevice();
1807 const DeviceInterface& vk = ctx.getDeviceInterface();
1809 const deUint32 inputStride = getLayoutStride(m_inputLayout);
1810 const int inputBufferSize = inputStride * numValues;
1812 if (inputBufferSize == 0)
1813 return; // No inputs
1815 DE_ASSERT(m_shaderSpec.inputs.size() == m_inputLayout.size());
1816 for (size_t inputNdx = 0; inputNdx < m_shaderSpec.inputs.size(); ++inputNdx)
1818 const glu::VarType& varType = m_shaderSpec.inputs[inputNdx].varType;
1819 const VarLayout& layout = m_inputLayout[inputNdx];
1821 copyToBuffer(varType, layout, numValues, inputPtrs[inputNdx], m_inputAlloc->getHostPtr());
1824 flushMappedMemoryRange(vk, vkDevice, m_inputAlloc->getMemory(), m_inputAlloc->getOffset(), inputBufferSize);
1827 void BufferIoExecutor::readOutputBuffer (const Context& ctx, void* const* outputPtrs, int numValues)
1829 const VkDevice vkDevice = ctx.getDevice();
1830 const DeviceInterface& vk = ctx.getDeviceInterface();
1832 const deUint32 outputStride = getLayoutStride(m_outputLayout);
1833 const int outputBufferSize = numValues * outputStride;
1835 DE_ASSERT(outputBufferSize > 0); // At least some outputs are required.
1837 invalidateMappedMemoryRange(vk, vkDevice, m_outputAlloc->getMemory(), m_outputAlloc->getOffset(), outputBufferSize);
1839 DE_ASSERT(m_shaderSpec.outputs.size() == m_outputLayout.size());
1840 for (size_t outputNdx = 0; outputNdx < m_shaderSpec.outputs.size(); ++outputNdx)
1842 const glu::VarType& varType = m_shaderSpec.outputs[outputNdx].varType;
1843 const VarLayout& layout = m_outputLayout[outputNdx];
1845 copyFromBuffer(varType, layout, numValues, m_outputAlloc->getHostPtr(), outputPtrs[outputNdx]);
1849 void BufferIoExecutor::initBuffers (const Context& ctx, int numValues)
1851 const deUint32 inputStride = getLayoutStride(m_inputLayout);
1852 const deUint32 outputStride = getLayoutStride(m_outputLayout);
1853 // Avoid creating zero-sized buffer/memory
1854 const size_t inputBufferSize = numValues * inputStride ? (numValues * inputStride) : 1;
1855 const size_t outputBufferSize = numValues * outputStride;
1857 // Upload data to buffer
1858 const VkDevice vkDevice = ctx.getDevice();
1859 const DeviceInterface& vk = ctx.getDeviceInterface();
1860 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex();
1861 Allocator& memAlloc = ctx.getDefaultAllocator();
1863 const VkBufferCreateInfo inputBufferParams =
1865 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1866 DE_NULL, // const void* pNext;
1867 0u, // VkBufferCreateFlags flags;
1868 inputBufferSize, // VkDeviceSize size;
1869 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
1870 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1871 1u, // deUint32 queueFamilyCount;
1872 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1875 m_inputBuffer = createBuffer(vk, vkDevice, &inputBufferParams);
1876 m_inputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_inputBuffer), MemoryRequirement::HostVisible);
1878 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_inputBuffer, m_inputAlloc->getMemory(), m_inputAlloc->getOffset()));
1880 const VkBufferCreateInfo outputBufferParams =
1882 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1883 DE_NULL, // const void* pNext;
1884 0u, // VkBufferCreateFlags flags;
1885 outputBufferSize, // VkDeviceSize size;
1886 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
1887 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1888 1u, // deUint32 queueFamilyCount;
1889 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1892 m_outputBuffer = createBuffer(vk, vkDevice, &outputBufferParams);
1893 m_outputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_outputBuffer), MemoryRequirement::HostVisible);
1895 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_outputBuffer, m_outputAlloc->getMemory(), m_outputAlloc->getOffset()));
1898 // ComputeShaderExecutor
1900 class ComputeShaderExecutor : public BufferIoExecutor
1903 ComputeShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1904 virtual ~ComputeShaderExecutor (void);
1906 virtual void setShaderSources (SourceCollections& programCollection) const;
1908 virtual void execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs);
1911 static std::string generateComputeShader (const ShaderSpec& spec);
1914 ComputeShaderExecutor::ComputeShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1915 : BufferIoExecutor (shaderSpec, shaderType)
1919 ComputeShaderExecutor::~ComputeShaderExecutor (void)
1923 std::string ComputeShaderExecutor::generateComputeShader (const ShaderSpec& spec)
1925 std::ostringstream src;
1926 src << "#version 310 es\n"
1927 "#extension GL_ARB_separate_shader_objects : enable\n"
1928 "#extension GL_ARB_shading_language_420pack : enable\n";
1930 if (!spec.globalDeclarations.empty())
1931 src << spec.globalDeclarations << "\n";
1933 src << "layout(local_size_x = 1) in;\n"
1936 declareBufferBlocks(src, spec);
1938 src << "void main (void)\n"
1940 << " uint invocationNdx = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z\n"
1941 << " + gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n";
1943 generateExecBufferIo(src, spec, "invocationNdx");
1950 void ComputeShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1952 programCollection.glslSources.add("compute") << glu::ComputeSource(generateComputeShader(m_shaderSpec));
1955 void ComputeShaderExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs)
1957 checkSupported(ctx, m_shaderType);
1959 const VkDevice vkDevice = ctx.getDevice();
1960 const DeviceInterface& vk = ctx.getDeviceInterface();
1961 const VkQueue queue = ctx.getUniversalQueue();
1962 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex();
1963 Allocator& memAlloc = ctx.getDefaultAllocator();
1965 Move<VkShaderModule> computeShaderModule;
1966 Move<VkPipeline> computePipeline;
1967 Move<VkPipelineLayout> pipelineLayout;
1968 Move<VkCommandPool> cmdPool;
1969 Move<VkDescriptorPool> descriptorPool;
1970 Move<VkDescriptorSetLayout> descriptorSetLayout;
1971 Move<VkDescriptorSet> descriptorSet;
1972 Move<VkFence> fence;
1974 initBuffers(ctx, numValues);
1976 // Setup input buffer & copy data
1977 uploadInputBuffer(ctx, inputs, numValues);
1979 // Create command pool
1981 const VkCommandPoolCreateInfo cmdPoolParams =
1983 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
1984 DE_NULL, // const void* pNext;
1985 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
1986 queueFamilyIndex // deUint32 queueFamilyIndex;
1989 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1992 // Create command buffer
1993 const VkCommandBufferAllocateInfo cmdBufferParams =
1995 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1996 DE_NULL, // const void* pNext;
1997 *cmdPool, // VkCmdPool cmdPool;
1998 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1999 1u // deUint32 bufferCount;
2002 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
2004 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
2005 DE_NULL, // const void* pNext;
2006 0u, // VkCmdBufferOptimizeFlags flags;
2007 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2010 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
2011 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2012 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
2013 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2015 addUniforms(vkDevice, vk, queueFamilyIndex, memAlloc);
2017 descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
2018 descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2020 const VkDescriptorSetAllocateInfo allocInfo =
2022 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2026 &*descriptorSetLayout
2029 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2031 // Create pipeline layout
2033 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2035 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
2036 DE_NULL, // const void* pNext;
2037 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
2038 1u, // deUint32 CdescriptorSetCount;
2039 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
2040 0u, // deUint32 pushConstantRangeCount;
2041 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
2044 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2049 computeShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("compute"), 0);
2054 const VkPipelineShaderStageCreateInfo shaderStageParams[1] =
2057 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2058 DE_NULL, // const void* pNext;
2059 (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
2060 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagsBit stage;
2061 *computeShaderModule, // VkShaderModule shader;
2062 "main", // const char* pName;
2063 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2067 const VkComputePipelineCreateInfo computePipelineParams =
2069 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
2070 DE_NULL, // const void* pNext;
2071 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
2072 *shaderStageParams, // VkPipelineShaderStageCreateInfo cs;
2073 *pipelineLayout, // VkPipelineLayout layout;
2074 0u, // VkPipeline basePipelineHandle;
2075 0u, // int32_t basePipelineIndex;
2078 computePipeline = createComputePipeline(vk, vkDevice, DE_NULL, &computePipelineParams);
2083 const VkFenceCreateInfo fenceParams =
2085 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
2086 DE_NULL, // const void* pNext;
2087 0u // VkFenceCreateFlags flags;
2089 fence = createFence(vk, vkDevice, &fenceParams);
2093 const int maxValuesPerInvocation = ctx.getDeviceProperties().limits.maxComputeWorkGroupSize[0];
2095 const deUint32 inputStride = getInputStride();
2096 const deUint32 outputStride = getOutputStride();
2098 while (curOffset < numValues)
2100 Move<VkCommandBuffer> cmdBuffer;
2101 const int numToExec = de::min(maxValuesPerInvocation, numValues-curOffset);
2103 // Update descriptors
2105 DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2107 const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2109 *m_outputBuffer, // VkBuffer buffer;
2110 curOffset * outputStride, // VkDeviceSize offset;
2111 numToExec * outputStride // VkDeviceSize range;
2114 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2118 const VkDescriptorBufferInfo inputDescriptorBufferInfo =
2120 *m_inputBuffer, // VkBuffer buffer;
2121 curOffset * inputStride, // VkDeviceSize offset;
2122 numToExec * inputStride // VkDeviceSize range;
2125 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2128 uploadUniforms(descriptorSetUpdateBuilder, *descriptorSet);
2130 descriptorSetUpdateBuilder.update(vk, vkDevice);
2133 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
2134 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2135 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
2137 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
2139 vk.cmdDispatch(*cmdBuffer, numToExec, 1, 1);
2141 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2143 curOffset += numToExec;
2147 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2149 const VkSubmitInfo submitInfo =
2151 VK_STRUCTURE_TYPE_SUBMIT_INFO,
2154 (const VkSemaphore*)DE_NULL,
2155 (const VkPipelineStageFlags*)DE_NULL,
2159 (const VkSemaphore*)DE_NULL,
2162 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2163 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2168 readOutputBuffer(ctx, outputs, numValues);
2171 // Tessellation utils
2173 static std::string generateVertexShaderForTess (void)
2175 std::ostringstream src;
2176 src << "#version 310 es\n"
2177 << "void main (void)\n{\n"
2178 << " gl_Position = vec4(gl_VertexIndex/2, gl_VertexIndex%2, 0.0, 1.0);\n"
2184 class TessellationExecutor : public BufferIoExecutor
2187 TessellationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
2188 virtual ~TessellationExecutor (void);
2190 void renderTess (const Context& ctx, deUint32 vertexCount);
2193 TessellationExecutor::TessellationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2194 : BufferIoExecutor (shaderSpec, shaderType)
2198 TessellationExecutor::~TessellationExecutor (void)
2202 void TessellationExecutor::renderTess (const Context& ctx, deUint32 vertexCount)
2204 const size_t inputBufferSize = (vertexCount/2) * getInputStride();
2205 const VkDevice vkDevice = ctx.getDevice();
2206 const DeviceInterface& vk = ctx.getDeviceInterface();
2207 const VkQueue queue = ctx.getUniversalQueue();
2208 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex();
2209 Allocator& memAlloc = ctx.getDefaultAllocator();
2211 const tcu::UVec2 renderSize (DEFAULT_RENDER_WIDTH, DEFAULT_RENDER_HEIGHT);
2213 Move<VkImage> colorImage;
2214 de::MovePtr<Allocation> colorImageAlloc;
2215 VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
2216 Move<VkImageView> colorImageView;
2218 Move<VkRenderPass> renderPass;
2219 Move<VkFramebuffer> framebuffer;
2220 Move<VkPipelineLayout> pipelineLayout;
2221 Move<VkPipeline> graphicsPipeline;
2223 Move<VkShaderModule> vertexShaderModule;
2224 Move<VkShaderModule> tessControlShaderModule;
2225 Move<VkShaderModule> tessEvalShaderModule;
2226 Move<VkShaderModule> fragmentShaderModule;
2228 Move<VkCommandPool> cmdPool;
2229 Move<VkCommandBuffer> cmdBuffer;
2231 Move<VkFence> fence;
2233 Move<VkDescriptorPool> descriptorPool;
2234 Move<VkDescriptorSetLayout> descriptorSetLayout;
2235 Move<VkDescriptorSet> descriptorSet;
2237 // Create color image
2239 const VkImageCreateInfo colorImageParams =
2241 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2242 DE_NULL, // const void* pNext;
2243 0u, // VkImageCreateFlags flags;
2244 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2245 colorFormat, // VkFormat format;
2246 { renderSize.x(), renderSize.y(), 1u }, // VkExtent3D extent;
2247 1u, // deUint32 mipLevels;
2248 1u, // deUint32 arraySize;
2249 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2250 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2251 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
2252 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2253 1u, // deUint32 queueFamilyCount;
2254 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2255 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
2258 colorImage = createImage(vk, vkDevice, &colorImageParams);
2260 // Allocate and bind color image memory
2261 colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *colorImage), MemoryRequirement::Any);
2262 VK_CHECK(vk.bindImageMemory(vkDevice, *colorImage, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
2265 // Create color attachment view
2267 const VkImageViewCreateInfo colorImageViewParams =
2269 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2270 DE_NULL, // const void* pNext;
2271 0u, // VkImageViewCreateFlags flags;
2272 *colorImage, // VkImage image;
2273 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2274 colorFormat, // VkFormat format;
2276 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
2277 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
2278 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
2279 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
2280 }, // VkComponentsMapping components;
2282 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2283 0u, // deUint32 baseMipLevel;
2284 1u, // deUint32 mipLevels;
2285 0u, // deUint32 baseArraylayer;
2286 1u // deUint32 layerCount;
2287 } // VkImageSubresourceRange subresourceRange;
2290 colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
2293 // Create render pass
2295 const VkAttachmentDescription colorAttachmentDescription =
2297 0u, // VkAttachmentDescriptorFlags flags;
2298 colorFormat, // VkFormat format;
2299 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2300 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
2301 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2302 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2303 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
2304 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
2305 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
2308 const VkAttachmentDescription attachments[1] =
2310 colorAttachmentDescription
2313 const VkAttachmentReference colorAttachmentReference =
2315 0u, // deUint32 attachment;
2316 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
2319 const VkSubpassDescription subpassDescription =
2321 0u, // VkSubpassDescriptionFlags flags;
2322 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
2323 0u, // deUint32 inputCount;
2324 DE_NULL, // const VkAttachmentReference* pInputAttachments;
2325 1u, // deUint32 colorCount;
2326 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
2327 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
2328 DE_NULL, // VkAttachmentReference depthStencilAttachment;
2329 0u, // deUint32 preserveCount;
2330 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
2333 const VkRenderPassCreateInfo renderPassParams =
2335 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
2336 DE_NULL, // const void* pNext;
2337 0u, // VkRenderPassCreateFlags flags;
2338 1u, // deUint32 attachmentCount;
2339 attachments, // const VkAttachmentDescription* pAttachments;
2340 1u, // deUint32 subpassCount;
2341 &subpassDescription, // const VkSubpassDescription* pSubpasses;
2342 0u, // deUint32 dependencyCount;
2343 DE_NULL // const VkSubpassDependency* pDependencies;
2346 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
2349 // Create framebuffer
2351 const VkFramebufferCreateInfo framebufferParams =
2353 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
2354 DE_NULL, // const void* pNext;
2355 0u, // VkFramebufferCreateFlags flags;
2356 *renderPass, // VkRenderPass renderPass;
2357 1u, // deUint32 attachmentCount;
2358 &*colorImageView, // const VkAttachmentBindInfo* pAttachments;
2359 (deUint32)renderSize.x(), // deUint32 width;
2360 (deUint32)renderSize.y(), // deUint32 height;
2361 1u // deUint32 layers;
2364 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
2367 // Create descriptors
2369 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2370 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2371 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2372 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2374 addUniforms(vkDevice, vk, queueFamilyIndex, memAlloc);
2376 descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
2377 descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2379 const VkDescriptorSetAllocateInfo allocInfo =
2381 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2385 &*descriptorSetLayout
2388 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2389 // Update descriptors
2391 DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2392 const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2394 *m_outputBuffer, // VkBuffer buffer;
2395 0u, // VkDeviceSize offset;
2396 VK_WHOLE_SIZE // VkDeviceSize range;
2399 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2401 VkDescriptorBufferInfo inputDescriptorBufferInfo =
2403 0, // VkBuffer buffer;
2404 0u, // VkDeviceSize offset;
2405 VK_WHOLE_SIZE // VkDeviceSize range;
2407 if (inputBufferSize)
2409 inputDescriptorBufferInfo.buffer = *m_inputBuffer;
2411 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2414 uploadUniforms(descriptorSetUpdateBuilder, *descriptorSet);
2416 descriptorSetUpdateBuilder.update(vk, vkDevice);
2420 // Create pipeline layout
2422 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2424 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
2425 DE_NULL, // const void* pNext;
2426 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
2427 1u, // deUint32 descriptorSetCount;
2428 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
2429 0u, // deUint32 pushConstantRangeCount;
2430 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
2433 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2436 // Create shader modules
2438 vertexShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("vert"), 0);
2439 tessControlShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("tess_control"), 0);
2440 tessEvalShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("tess_eval"), 0);
2441 fragmentShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("frag"), 0);
2446 const VkPipelineShaderStageCreateInfo shaderStageParams[4] =
2449 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2450 DE_NULL, // const void* pNext;
2451 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2452 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBit stage;
2453 *vertexShaderModule, // VkShaderModule shader;
2454 "main", // const char* pName;
2455 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2458 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2459 DE_NULL, // const void* pNext;
2460 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2461 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, // VkShaderStageFlagBit stage;
2462 *tessControlShaderModule, // VkShaderModule shader;
2463 "main", // const char* pName;
2464 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2467 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2468 DE_NULL, // const void* pNext;
2469 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2470 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, // VkShaderStageFlagBit stage;
2471 *tessEvalShaderModule, // VkShaderModule shader;
2472 "main", // const char* pName;
2473 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2476 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2477 DE_NULL, // const void* pNext;
2478 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2479 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBit stage;
2480 *fragmentShaderModule, // VkShaderModule shader;
2481 "main", // const char* pName;
2482 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2486 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
2488 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
2489 DE_NULL, // const void* pNext;
2490 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
2491 0u, // deUint32 bindingCount;
2492 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
2493 0u, // deUint32 attributeCount;
2494 DE_NULL, // const VkVertexInputAttributeDescription* pvertexAttributeDescriptions;
2497 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
2499 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
2500 DE_NULL, // const void* pNext;
2501 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2502 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, // VkPrimitiveTopology topology;
2503 DE_FALSE // VkBool32 primitiveRestartEnable;
2506 struct VkPipelineTessellationStateCreateInfo tessellationStateParams =
2508 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
2509 DE_NULL, // const void* pNext;
2510 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags;
2511 1 // uint32_t patchControlPoints;
2514 const VkViewport viewport =
2516 0.0f, // float originX;
2517 0.0f, // float originY;
2518 (float)renderSize.x(), // float width;
2519 (float)renderSize.y(), // float height;
2520 0.0f, // float minDepth;
2521 1.0f // float maxDepth;
2524 const VkRect2D scissor =
2529 }, // VkOffset2D offset;
2531 renderSize.x(), // deUint32 width;
2532 renderSize.y(), // deUint32 height;
2533 }, // VkExtent2D extent;
2536 const VkPipelineViewportStateCreateInfo viewportStateParams =
2538 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
2539 DE_NULL, // const void* pNext;
2540 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewPortStateCreateFlags flags;
2541 1u, // deUint32 viewportCount;
2542 &viewport, // const VkViewport* pViewports;
2543 1u, // deUint32 scissorsCount;
2544 &scissor // const VkRect2D* pScissors;
2547 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
2549 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
2550 DE_NULL, // const void* pNext;
2551 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStageCreateFlags flags;
2552 VK_FALSE, // VkBool32 depthClipEnable;
2553 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
2554 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
2555 VK_CULL_MODE_NONE, // VkCullMode cullMode;
2556 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
2557 VK_FALSE, // VkBool32 depthBiasEnable;
2558 0.0f, // float depthBias;
2559 0.0f, // float depthBiasClamp;
2560 0.0f, // float slopeScaledDepthBias;
2561 1.0f // float lineWidth;
2564 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
2566 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
2567 DE_NULL, // const void* pNext;
2568 0u, // VkPipelineMultisampleStateCreateFlags flags;
2569 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
2570 VK_FALSE, // VkBool32 sampleShadingEnable;
2571 0.0f, // float minSampleShading;
2572 DE_NULL, // const VkSampleMask* pSampleMask;
2573 VK_FALSE, // VkBool32 alphaToCoverageEnable;
2574 VK_FALSE // VkBool32 alphaToOneEnable;
2577 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
2579 VK_FALSE, // VkBool32 blendEnable;
2580 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcBlendColor;
2581 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destBlendColor;
2582 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
2583 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcBlendAlpha;
2584 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destBlendAlpha;
2585 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
2586 (VK_COLOR_COMPONENT_R_BIT |
2587 VK_COLOR_COMPONENT_G_BIT |
2588 VK_COLOR_COMPONENT_B_BIT |
2589 VK_COLOR_COMPONENT_A_BIT) // VkColorComponentFlags colorWriteMask;
2592 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
2594 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
2595 DE_NULL, // const void* pNext;
2596 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags
2597 VK_FALSE, // VkBool32 logicOpEnable;
2598 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
2599 1u, // deUint32 attachmentCount;
2600 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
2601 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConst[4];
2604 const VkPipelineDynamicStateCreateInfo dynamicStateInfo =
2606 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
2607 DE_NULL, // const void* pNext;
2608 (VkPipelineDynamicStateCreateFlags)0, // VkPipelineDynamicStateCreateFlags flags;
2609 0u, // deUint32 dynamicStateCount;
2610 DE_NULL // const VkDynamicState* pDynamicStates;
2613 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
2615 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
2616 DE_NULL, // const void* pNext;
2617 0u, // VkPipelineCreateFlags flags;
2618 4u, // deUint32 stageCount;
2619 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages;
2620 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
2621 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
2622 &tessellationStateParams, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
2623 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
2624 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
2625 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
2626 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
2627 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
2628 &dynamicStateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
2629 *pipelineLayout, // VkPipelineLayout layout;
2630 *renderPass, // VkRenderPass renderPass;
2631 0u, // deUint32 subpass;
2632 0u, // VkPipeline basePipelineHandle;
2633 0u // deInt32 basePipelineIndex;
2636 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
2639 // Create command pool
2641 const VkCommandPoolCreateInfo cmdPoolParams =
2643 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
2644 DE_NULL, // const void* pNext;
2645 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
2646 queueFamilyIndex, // deUint32 queueFamilyIndex;
2649 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
2652 // Create command buffer
2654 const VkCommandBufferAllocateInfo cmdBufferParams =
2656 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
2657 DE_NULL, // const void* pNext;
2658 *cmdPool, // VkCmdPool cmdPool;
2659 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
2660 1u // uint32_t bufferCount;
2663 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
2665 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
2666 DE_NULL, // const void* pNext;
2667 0u, // VkCmdBufferOptimizeFlags flags;
2668 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2671 const VkClearValue clearValues[1] =
2673 getDefaultClearColor()
2676 const VkRenderPassBeginInfo renderPassBeginInfo =
2678 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
2679 DE_NULL, // const void* pNext;
2680 *renderPass, // VkRenderPass renderPass;
2681 *framebuffer, // VkFramebuffer framebuffer;
2682 { { 0, 0 }, { renderSize.x(), renderSize.y() } }, // VkRect2D renderArea;
2683 1, // deUint32 attachmentCount;
2684 clearValues // const VkClearValue* pClearValues;
2687 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
2689 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2691 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2693 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
2695 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
2697 vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
2699 vk.cmdEndRenderPass(*cmdBuffer);
2700 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2705 const VkFenceCreateInfo fenceParams =
2707 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
2708 DE_NULL, // const void* pNext;
2709 0u // VkFenceCreateFlags flags;
2711 fence = createFence(vk, vkDevice, &fenceParams);
2716 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2717 const VkSubmitInfo submitInfo =
2719 VK_STRUCTURE_TYPE_SUBMIT_INFO,
2722 (const VkSemaphore*)0,
2723 (const VkPipelineStageFlags*)DE_NULL,
2727 (const VkSemaphore*)0,
2729 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2730 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2734 // TessControlExecutor
2736 class TessControlExecutor : public TessellationExecutor
2739 TessControlExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
2740 virtual ~TessControlExecutor (void);
2742 virtual void setShaderSources (SourceCollections& programCollection) const;
2744 virtual void execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs);
2747 static std::string generateTessControlShader (const ShaderSpec& shaderSpec);
2750 TessControlExecutor::TessControlExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2751 : TessellationExecutor (shaderSpec, shaderType)
2755 TessControlExecutor::~TessControlExecutor (void)
2759 std::string TessControlExecutor::generateTessControlShader (const ShaderSpec& shaderSpec)
2761 std::ostringstream src;
2762 src << "#version 310 es\n"
2763 "#extension GL_EXT_tessellation_shader : require\n\n"
2764 "#extension GL_ARB_separate_shader_objects : enable\n"
2765 "#extension GL_ARB_shading_language_420pack : enable\n";
2767 if (!shaderSpec.globalDeclarations.empty())
2768 src << shaderSpec.globalDeclarations << "\n";
2770 src << "\nlayout(vertices = 1) out;\n\n";
2772 declareBufferBlocks(src, shaderSpec);
2774 src << "void main (void)\n{\n";
2776 for (int ndx = 0; ndx < 2; ndx++)
2777 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2779 for (int ndx = 0; ndx < 4; ndx++)
2780 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2783 << "\thighp uint invocationId = uint(gl_PrimitiveID);\n";
2785 generateExecBufferIo(src, shaderSpec, "invocationId");
2792 static std::string generateEmptyTessEvalShader ()
2794 std::ostringstream src;
2796 src << "#version 310 es\n"
2797 "#extension GL_EXT_tessellation_shader : require\n\n"
2798 "#extension GL_ARB_separate_shader_objects : enable\n"
2799 "#extension GL_ARB_shading_language_420pack : enable\n";
2801 src << "layout(triangles, ccw) in;\n";
2803 src << "\nvoid main (void)\n{\n"
2804 << "\tgl_Position = vec4(gl_TessCoord.xy, 0.0, 1.0);\n"
2810 void TessControlExecutor::setShaderSources (SourceCollections& programCollection) const
2812 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess());
2813 programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generateTessControlShader(m_shaderSpec));
2814 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateEmptyTessEvalShader());
2815 programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource());
2818 void TessControlExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs)
2820 checkSupported(ctx, m_shaderType);
2822 initBuffers(ctx, numValues);
2824 // Setup input buffer & copy data
2825 uploadInputBuffer(ctx, inputs, numValues);
2827 renderTess(ctx, 3 * numValues);
2830 readOutputBuffer(ctx, outputs, numValues);
2833 // TessEvaluationExecutor
2835 class TessEvaluationExecutor : public TessellationExecutor
2838 TessEvaluationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
2839 virtual ~TessEvaluationExecutor (void);
2841 virtual void setShaderSources (SourceCollections& programCollection) const;
2843 virtual void execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs);
2846 static std::string generateTessEvalShader (const ShaderSpec& shaderSpec);
2849 TessEvaluationExecutor::TessEvaluationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2850 : TessellationExecutor (shaderSpec, shaderType)
2854 TessEvaluationExecutor::~TessEvaluationExecutor (void)
2858 static std::string generatePassthroughTessControlShader (void)
2860 std::ostringstream src;
2862 src << "#version 310 es\n"
2863 "#extension GL_EXT_tessellation_shader : require\n\n"
2864 "#extension GL_ARB_separate_shader_objects : enable\n"
2865 "#extension GL_ARB_shading_language_420pack : enable\n";
2867 src << "layout(vertices = 1) out;\n\n";
2869 src << "void main (void)\n{\n";
2871 for (int ndx = 0; ndx < 2; ndx++)
2872 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2874 for (int ndx = 0; ndx < 4; ndx++)
2875 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2882 std::string TessEvaluationExecutor::generateTessEvalShader (const ShaderSpec& shaderSpec)
2884 std::ostringstream src;
2886 src << "#version 310 es\n"
2887 "#extension GL_EXT_tessellation_shader : require\n\n"
2888 "#extension GL_ARB_separate_shader_objects : enable\n"
2889 "#extension GL_ARB_shading_language_420pack : enable\n";
2891 if (!shaderSpec.globalDeclarations.empty())
2892 src << shaderSpec.globalDeclarations << "\n";
2896 src << "layout(isolines, equal_spacing) in;\n\n";
2898 declareBufferBlocks(src, shaderSpec);
2900 src << "void main (void)\n{\n"
2901 << "\tgl_Position = vec4(gl_TessCoord.x, 0.0, 0.0, 1.0);\n"
2902 << "\thighp uint invocationId = uint(gl_PrimitiveID) + (gl_TessCoord.x > 0.5 ? 1u : 0u);\n";
2904 generateExecBufferIo(src, shaderSpec, "invocationId");
2911 void TessEvaluationExecutor::setShaderSources (SourceCollections& programCollection) const
2913 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess());
2914 programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generatePassthroughTessControlShader());
2915 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateTessEvalShader(m_shaderSpec));
2916 programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource());
2919 void TessEvaluationExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs)
2921 checkSupported(ctx, m_shaderType);
2923 const int alignedValues = deAlign32(numValues, 2);
2925 // Initialize buffers with aligned value count to make room for padding
2926 initBuffers(ctx, alignedValues);
2928 // Setup input buffer & copy data
2929 uploadInputBuffer(ctx, inputs, numValues);
2931 renderTess(ctx, 2 * numValues);
2934 readOutputBuffer(ctx, outputs, numValues);
2941 ShaderExecutor::ShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2942 : m_shaderSpec (shaderSpec)
2943 , m_shaderType (shaderType)
2947 ShaderExecutor::~ShaderExecutor (void)
2953 ShaderExecutor* createExecutor (glu::ShaderType shaderType, const ShaderSpec& shaderSpec)
2957 case glu::SHADERTYPE_VERTEX: return new VertexShaderExecutor (shaderSpec, shaderType);
2958 case glu::SHADERTYPE_TESSELLATION_CONTROL: return new TessControlExecutor (shaderSpec, shaderType);
2959 case glu::SHADERTYPE_TESSELLATION_EVALUATION: return new TessEvaluationExecutor (shaderSpec, shaderType);
2960 case glu::SHADERTYPE_GEOMETRY: return new GeometryShaderExecutor (shaderSpec, shaderType);
2961 case glu::SHADERTYPE_FRAGMENT: return new FragmentShaderExecutor (shaderSpec, shaderType);
2962 case glu::SHADERTYPE_COMPUTE: return new ComputeShaderExecutor (shaderSpec, shaderType);
2964 throw tcu::InternalError("Unsupported shader type");
2968 void ShaderExecutor::setupUniformData (const VkDevice& vkDevice,
2969 const DeviceInterface& vk,
2970 const deUint32 queueFamilyIndex,
2971 Allocator& memAlloc,
2972 deUint32 bindingLocation,
2973 VkDescriptorType descriptorType,
2975 const void* dataPtr)
2977 DE_ASSERT(descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2979 VkImageUsageFlags usage = descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
2981 const VkBufferCreateInfo uniformBufferParams =
2983 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2984 DE_NULL, // const void* pNext;
2985 0u, // VkBufferCreateFlags flags;
2986 size, // VkDeviceSize size;
2987 usage, // VkBufferUsageFlags usage;
2988 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2989 1u, // deUint32 queueFamilyIndexCount;
2990 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
2993 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &uniformBufferParams);
2994 de::MovePtr<Allocation> alloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
2995 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
2997 deMemcpy(alloc->getHostPtr(), dataPtr, size);
2998 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), size);
3000 de::MovePtr<BufferUniform> uniformInfo(new BufferUniform());
3001 uniformInfo->type = descriptorType;
3002 uniformInfo->descriptor = makeDescriptorBufferInfo(*buffer, 0u, size);
3003 uniformInfo->location = bindingLocation;
3004 uniformInfo->buffer = VkBufferSp(new Unique<VkBuffer>(buffer));
3005 uniformInfo->alloc = AllocationSp(alloc.release());
3007 m_descriptorSetLayoutBuilder.addSingleBinding(descriptorType, VK_SHADER_STAGE_ALL);
3008 m_descriptorPoolBuilder.addType(descriptorType);
3010 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniformInfo)));
3013 void ShaderExecutor::setupSamplerData (const VkDevice& vkDevice,
3014 const DeviceInterface& vk,
3015 const deUint32 queueFamilyIndex,
3016 Allocator& memAlloc,
3017 deUint32 bindingLocation,
3018 deUint32 numSamplers,
3019 const tcu::Sampler& refSampler,
3020 const tcu::TextureFormat& texFormat,
3021 const tcu::IVec3& texSize,
3022 VkImageType imageType,
3023 VkImageViewType imageViewType,
3026 DE_ASSERT(numSamplers > 0);
3028 std::vector<VkSampler> vkSamplers;
3029 de::MovePtr<SamplerArrayUniform> samplers (new SamplerArrayUniform());
3031 samplers->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
3032 samplers->location = bindingLocation;
3034 for (deUint32 ndx = 0; ndx < numSamplers; ++ndx)
3036 const int offset = ndx * texSize.x() * texSize.y() * texSize.z() * texFormat.getPixelSize();
3037 const void* samplerData = ((deUint8*)data) + offset;
3038 de::MovePtr<SamplerUniform> uniform = createSamplerUniform(vkDevice, vk, queueFamilyIndex, memAlloc, bindingLocation, refSampler, texFormat, texSize, imageType, imageViewType, samplerData);
3040 vkSamplers.push_back(uniform->sampler.get()->get());
3042 samplers->uniforms.push_back(SamplerUniformSp(new de::UniquePtr<SamplerUniform>(uniform)));
3045 m_descriptorSetLayoutBuilder.addArraySamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, numSamplers, VK_SHADER_STAGE_ALL, &vkSamplers[0]);
3046 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, numSamplers);
3048 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(samplers)));
3051 const void* ShaderExecutor::getBufferPtr (const deUint32 bindingLocation) const
3053 std::vector<UniformInfoSp>::const_iterator it = m_uniformInfos.begin();
3054 for (; it != m_uniformInfos.end(); it++)
3056 const UniformInfo* uniformInfo = it->get()->get();
3057 if (uniformInfo->isBufferUniform() && uniformInfo->location == bindingLocation)
3059 const BufferUniform* bufferUniform = static_cast<const BufferUniform*>(uniformInfo);
3060 return bufferUniform->alloc->getHostPtr();
3067 void ShaderExecutor::addUniforms (const VkDevice& vkDevice, const DeviceInterface& vk, const deUint32 queueFamilyIndex, Allocator& memAlloc)
3069 if (!m_uniformSetup)
3072 for (std::vector<UniformDataSp>::const_iterator it = m_uniformSetup->uniforms().begin(); it != m_uniformSetup->uniforms().end(); ++it)
3074 const UniformDataBase* uniformData = it->get()->get();
3075 uniformData->setup(*this, vkDevice, vk, queueFamilyIndex, memAlloc);
3079 void ShaderExecutor::uploadUniforms (DescriptorSetUpdateBuilder& descriptorSetUpdateBuilder, VkDescriptorSet descriptorSet)
3081 for (std::vector<UniformInfoSp>::const_iterator it = m_uniformInfos.begin(); it != m_uniformInfos.end(); ++it)
3083 const UniformInfo* uniformInfo = it->get()->get();
3085 if (uniformInfo->isSamplerArray())
3087 const SamplerArrayUniform* arrayInfo = static_cast<const SamplerArrayUniform*>(uniformInfo);
3088 std::vector<VkDescriptorImageInfo> descriptors;
3090 for (std::vector<SamplerUniformSp>::const_iterator ait = arrayInfo->uniforms.begin(); ait != arrayInfo->uniforms.end(); ++ait)
3092 descriptors.push_back(ait->get()->get()->descriptor);
3095 descriptorSetUpdateBuilder.writeArray(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(uniformInfo->location), uniformInfo->type, (deUint32)descriptors.size(), &descriptors[0]);
3097 else if (uniformInfo->isBufferUniform())
3099 const BufferUniform* bufferUniform = static_cast<const BufferUniform*>(uniformInfo);
3100 descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(bufferUniform->location), bufferUniform->type, &bufferUniform->descriptor);
3102 else if (uniformInfo->isSamplerUniform())
3104 const SamplerUniform* samplerUniform = static_cast<const SamplerUniform*>(uniformInfo);
3105 descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(samplerUniform->location), samplerUniform->type, &samplerUniform->descriptor);
3110 Move<VkImage> ShaderExecutor::createCombinedImage (const VkDevice& vkDevice,
3111 const DeviceInterface& vk,
3112 const deUint32 queueFamilyIndex,
3113 const tcu::IVec3& texSize,
3114 const VkFormat format,
3115 const VkImageType imageType,
3116 const VkImageViewType imageViewType,
3117 const VkImageUsageFlags usage,
3118 const VkImageTiling tiling)
3120 const bool isCube = imageViewType == vk::VK_IMAGE_VIEW_TYPE_CUBE;
3121 const VkImageCreateFlags flags = isCube ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlags)0;
3122 const deUint32 arraySize = isCube ? 6u : 1u;
3124 const VkImageCreateInfo imageCreateInfo =
3126 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3127 DE_NULL, // const void* pnext;
3128 flags, // VkImageCreateFlags flags;
3129 imageType, // VkImageType imageType;
3130 format, // VkFormat format;
3131 { (deUint32)texSize.x(), (deUint32)texSize.y(), (deUint32)texSize.z() }, // VkExtend3D extent;
3132 1u, // deUint32 mipLevels;
3133 arraySize, // deUint32 arraySize;
3134 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
3135 tiling, // VkImageTiling tiling;
3136 usage, // VkImageUsageFlags usage;
3137 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3138 1u, // deuint32 queueFamilyCount;
3139 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
3140 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
3143 Move<VkImage> vkTexture = createImage(vk, vkDevice, &imageCreateInfo);
3147 de::MovePtr<Allocation> ShaderExecutor::uploadImage (const VkDevice& vkDevice,
3148 const DeviceInterface& vk,
3149 Allocator& memAlloc,
3150 const tcu::TextureFormat& texFormat,
3151 const tcu::IVec3& texSize,
3153 const VkImage& vkTexture,
3154 const VkImageAspectFlags aspectMask)
3156 de::MovePtr<Allocation> allocation = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, vkTexture), MemoryRequirement::HostVisible);
3157 VK_CHECK(vk.bindImageMemory(vkDevice, vkTexture, allocation->getMemory(), allocation->getOffset()));
3159 const VkImageSubresource subres =
3161 aspectMask, // VkImageAspectFlags aspectMask;
3162 0u, // deUint32 mipLevel;
3163 0u // deUint32 arraySlice
3166 VkSubresourceLayout layout;
3167 vk.getImageSubresourceLayout(vkDevice, vkTexture, &subres, &layout);
3169 tcu::ConstPixelBufferAccess access (texFormat, texSize, data);
3170 tcu::PixelBufferAccess destAccess (texFormat, texSize, allocation->getHostPtr());
3172 tcu::copy(destAccess, access);
3174 flushMappedMemoryRange(vk, vkDevice, allocation->getMemory(), allocation, layout.size);
3179 de::MovePtr<ShaderExecutor::SamplerUniform> ShaderExecutor::createSamplerUniform (const VkDevice& vkDevice,
3180 const DeviceInterface& vk,
3181 const deUint32 queueFamilyIndex,
3182 Allocator& memAlloc,
3183 deUint32 bindingLocation,
3184 const tcu::Sampler& refSampler,
3185 const tcu::TextureFormat& texFormat,
3186 const tcu::IVec3& texSize,
3187 VkImageType imageType,
3188 VkImageViewType imageViewType,
3191 const VkFormat format = mapTextureFormat(texFormat);
3192 const bool isCube = imageViewType == VK_IMAGE_VIEW_TYPE_CUBE;
3193 const bool isShadowSampler = texFormat == tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
3194 const VkImageUsageFlags imageUsage = isShadowSampler ? (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) : VK_IMAGE_USAGE_SAMPLED_BIT;
3195 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
3196 const deUint32 arraySize = isCube ? 6u : 1u;
3197 Move<VkImage> vkTexture;
3198 de::MovePtr<Allocation> allocation;
3200 vkTexture = createCombinedImage(vkDevice, vk, queueFamilyIndex, texSize, format, imageType, imageViewType, imageUsage, VK_IMAGE_TILING_OPTIMAL);
3201 allocation = uploadImage(vkDevice, vk, memAlloc, texFormat, texSize, data, *vkTexture, aspectMask);
3204 const VkSamplerCreateInfo samplerParams = mapSampler(refSampler, texFormat);
3205 Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams);
3207 const VkImageViewCreateInfo viewParams =
3209 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
3210 NULL, // const voide* pNexŧ;
3211 0u, // VkImageViewCreateFlags flags;
3212 *vkTexture, // VkImage image;
3213 imageViewType, // VkImageViewType viewType;
3214 format, // VkFormat format;
3216 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
3217 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
3218 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
3219 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
3220 }, // VkComponentMapping components;
3222 aspectMask, // VkImageAspectFlags aspectMask;
3223 0, // deUint32 baseMipLevel;
3224 1, // deUint32 mipLevels;
3225 0, // deUint32 baseArraySlice;
3226 arraySize // deUint32 arraySize;
3227 } // VkImageSubresourceRange subresourceRange;
3230 Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams);
3232 const VkDescriptorImageInfo descriptor =
3234 sampler.get(), // VkSampler sampler;
3235 imageView.get(), // VkImageView imageView;
3236 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
3239 de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
3240 uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
3241 uniform->descriptor = descriptor;
3242 uniform->location = bindingLocation;
3243 uniform->image = VkImageSp(new Unique<VkImage>(vkTexture));
3244 uniform->imageView = VkImageViewSp(new Unique<VkImageView>(imageView));
3245 uniform->sampler = VkSamplerSp(new Unique<VkSampler>(sampler));
3246 uniform->alloc = AllocationSp(allocation.release());
3251 SamplerUniformData::SamplerUniformData (deUint32 bindingLocation,
3252 deUint32 numSamplers,
3253 const tcu::Sampler& refSampler,
3254 const tcu::TextureFormat& texFormat,
3255 const tcu::IVec3& texSize,
3256 VkImageType imageType,
3257 VkImageViewType imageViewType,
3259 : UniformDataBase (bindingLocation)
3260 , m_numSamplers (numSamplers)
3261 , m_refSampler (refSampler)
3262 , m_texFormat (texFormat)
3263 , m_texSize (texSize)
3264 , m_imageType (imageType)
3265 , m_imageViewType (imageViewType)
3270 SamplerUniformData::~SamplerUniformData (void)
3274 void SamplerUniformData::setup (ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const deUint32 queueFamilyIndex, Allocator& memAlloc) const
3276 executor.setupSamplerData(vkDevice, vk, queueFamilyIndex, memAlloc, m_bindingLocation, m_numSamplers, m_refSampler, m_texFormat, m_texSize, m_imageType, m_imageViewType, m_data);