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 deInt32 renderSizeX = de::min(static_cast<int>(DEFAULT_RENDER_WIDTH), numValues);
726 const deInt32 renderSizeY = (numValues / renderSizeX) + ((numValues % renderSizeX != 0) ? 1 : 0);
727 const tcu::IVec2 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);
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 0u, // 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 DE_NULL, // VkRenderPass renderPass;
1235 0u, // deUint32 subpass;
1236 DE_NULL, // VkFramebuffer framebuffer;
1237 VK_FALSE, // VkBool32 occlusionQueryEnable;
1238 (VkQueryControlFlags)0u, //VkQueryControlFlags queryFlags;
1239 (VkQueryPipelineStatisticFlags)0u //VkQueryPipelineStatisticFlags pipelineStatistics;
1242 const VkRenderPassBeginInfo renderPassBeginInfo =
1244 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
1245 DE_NULL, // const void* pNext;
1246 *renderPass, // VkRenderPass renderPass;
1247 *framebuffer, // VkFramebuffer framebuffer;
1248 { { 0, 0 }, { renderSize.x(), renderSize.y() } }, // VkRect2D renderArea;
1249 (deUint32)attachmentClearValues.size(), // deUint32 attachmentCount;
1250 &attachmentClearValues[0] // const VkClearValue* pAttachmentClearValues;
1253 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
1255 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1258 std::vector<const void*> barriers(colorImagePreRenderBarriers.size());
1259 if (!barriers.empty())
1261 for (size_t i = 0; i < barriers.size(); ++i)
1262 barriers[i] = &colorImagePreRenderBarriers[i];
1263 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_FALSE, (deUint32)barriers.size(), &barriers[0]);
1267 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1269 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
1270 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
1272 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size();
1274 std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0);
1276 std::vector<VkBuffer> buffers(numberOfVertexAttributes);
1277 for (size_t i = 0; i < numberOfVertexAttributes; i++)
1279 buffers[i] = m_vertexBuffers[i].get()->get();
1282 vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]);
1283 vk.cmdDraw(*cmdBuffer, (deUint32)positions.size(), 1u, 0u, 0u);
1285 vk.cmdEndRenderPass(*cmdBuffer);
1288 std::vector<const void*> barriers(colorImagePostRenderBarriers.size());
1289 if (!barriers.empty())
1291 for (size_t i = 0; i < barriers.size(); ++i)
1292 barriers[i] = &colorImagePostRenderBarriers[i];
1293 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_FALSE, (deUint32)barriers.size(), &barriers[0]);
1296 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1301 const VkFenceCreateInfo fenceParams =
1303 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
1304 DE_NULL, // const void* pNext;
1305 0u // VkFenceCreateFlags flags;
1308 fence = createFence(vk, vkDevice, &fenceParams);
1314 const VkSubmitInfo submitInfo =
1316 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
1318 0u, // waitSemaphoreCount
1319 DE_NULL, // pWaitSemaphores
1320 1u, // commandBufferCount
1321 &cmdBuffer.get(), // pCommandBuffers
1322 0u, // signalSemaphoreCount
1323 DE_NULL // pSignalSemaphores
1326 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1327 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1328 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), DE_TRUE, ~(0ull) /* infinity*/));
1331 // Read back result and output
1333 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(4 * sizeof(deUint32) * renderSize.x() * renderSize.y());
1334 const VkBufferCreateInfo readImageBufferParams =
1336 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1337 DE_NULL, // const void* pNext;
1338 0u, // VkBufferCreateFlags flags;
1339 imageSizeBytes, // VkDeviceSize size;
1340 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
1341 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1342 1u, // deUint32 queueFamilyCount;
1343 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1346 // constants for image copy
1348 const VkCommandPoolCreateInfo cmdPoolParams =
1350 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
1351 DE_NULL, // const void* pNext;
1352 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
1353 queueFamilyIndex // deUint32 queueFamilyIndex;
1356 Move<VkCommandPool> copyCmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1358 const VkCommandBufferAllocateInfo cmdBufferParams =
1360 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1361 DE_NULL, // const void* pNext;
1362 *copyCmdPool, // VkCmdPool cmdPool;
1363 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
1364 1u // deUint32 bufferCount;
1367 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1369 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1370 DE_NULL, // const void* pNext;
1371 0u, // VkCmdBufferOptimizeFlags flags;
1372 DE_NULL, // VkRenderPass renderPass;
1373 0u, // deUint32 subpass;
1374 DE_NULL, // VkFramebuffer framebuffer;
1375 VK_FALSE, // VkBool32 occlusionQueryEnable;
1376 (VkQueryControlFlags)0, // VkQueryControlFlags queryFlags;
1377 (VkQueryPipelineStatisticFlags)0 // VkQueryPipelineStatisticFlags pipelineStatistics;
1381 const VkBufferImageCopy copyParams =
1383 0u, // VkDeviceSize bufferOffset;
1384 (deUint32)renderSize.x(), // deUint32 bufferRowLength;
1385 (deUint32)renderSize.y(), // deUint32 bufferImageHeight;
1387 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
1388 0u, // deUint32 mipLevel;
1389 0u, // deUint32 arraySlice;
1390 1u, // deUint32 arraySize;
1391 }, // VkImageSubresource imageSubresource;
1392 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
1393 { renderSize.x(), renderSize.y(), 1u } // VkExtent3D imageExtent;
1396 // Read back pixels.
1397 for (int outNdx = 0; outNdx < (int)m_shaderSpec.outputs.size(); ++outNdx)
1399 const Symbol& output = m_shaderSpec.outputs[outNdx];
1400 const int outSize = output.varType.getScalarSize();
1401 const int outVecSize = glu::getDataTypeNumComponents(output.varType.getBasicType());
1402 const int outNumLocs = glu::getDataTypeNumLocations(output.varType.getBasicType());
1403 deUint32* dstPtrBase = static_cast<deUint32*>(outputs[outNdx]);
1404 const int outLocation = de::lookup(m_outputLayout.locationMap, output.name);
1406 for (int locNdx = 0; locNdx < outNumLocs; ++locNdx)
1408 tcu::TextureLevel tmpBuf;
1409 const tcu::TextureFormat format = getRenderbufferFormatForOutput(output.varType, false);
1410 const tcu::TextureFormat readFormat (tcu::TextureFormat::RGBA, format.type);
1411 const Unique<VkBuffer> readImageBuffer(createBuffer(vk, vkDevice, &readImageBufferParams));
1412 const de::UniquePtr<Allocation> readImageBufferMemory(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
1414 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
1416 // Copy image to buffer
1419 Move<VkCommandBuffer> copyCmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
1421 const VkSubmitInfo submitInfo =
1423 VK_STRUCTURE_TYPE_SUBMIT_INFO,
1426 (const VkSemaphore*)DE_NULL,
1428 ©CmdBuffer.get(),
1430 (const VkSemaphore*)DE_NULL,
1433 VK_CHECK(vk.beginCommandBuffer(*copyCmdBuffer, &cmdBufferBeginInfo));
1434 vk.cmdCopyImageToBuffer(*copyCmdBuffer, colorImages[outLocation + locNdx].get()->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params);
1435 VK_CHECK(vk.endCommandBuffer(*copyCmdBuffer));
1437 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
1438 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1439 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
1442 const VkMappedMemoryRange range =
1444 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
1445 DE_NULL, // const void* pNext;
1446 readImageBufferMemory->getMemory(), // VkDeviceMemory mem;
1447 0, // VkDeviceSize offset;
1448 imageSizeBytes, // VkDeviceSize size;
1451 VK_CHECK(vk.invalidateMappedMemoryRanges(vkDevice, 1u, &range));
1453 tmpBuf.setStorage(readFormat, renderSize.x(), renderSize.y());
1455 const tcu::TextureFormat resultFormat(tcu::TextureFormat::RGBA, format.type);
1456 const tcu::ConstPixelBufferAccess resultAccess(resultFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr());
1458 tcu::copy(tmpBuf.getAccess(), resultAccess);
1460 if (outSize == 4 && outNumLocs == 1)
1461 deMemcpy(dstPtrBase, tmpBuf.getAccess().getDataPtr(), numValues * outVecSize * sizeof(deUint32));
1464 for (int valNdx = 0; valNdx < numValues; valNdx++)
1466 const deUint32* srcPtr = (const deUint32*)tmpBuf.getAccess().getDataPtr() + valNdx * 4;
1467 deUint32* dstPtr = &dstPtrBase[outSize * valNdx + outVecSize * locNdx];
1468 deMemcpy(dstPtr, srcPtr, outVecSize * sizeof(deUint32));
1476 // VertexShaderExecutor
1478 class VertexShaderExecutor : public FragmentOutExecutor
1481 VertexShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1482 virtual ~VertexShaderExecutor (void);
1484 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst;}
1486 virtual void setShaderSources (SourceCollections& programCollection) const;
1490 VertexShaderExecutor::VertexShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1491 : FragmentOutExecutor (shaderSpec, shaderType)
1495 VertexShaderExecutor::~VertexShaderExecutor (void)
1499 void VertexShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1501 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShader(m_shaderSpec, "a_", "vtx_out_"));
1502 /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1503 programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(m_shaderSpec, false, m_outputLayout.locationMap, "vtx_out_", "o_"));
1506 // GeometryShaderExecutor
1508 class GeometryShaderExecutor : public FragmentOutExecutor
1511 GeometryShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1512 virtual ~GeometryShaderExecutor (void);
1514 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst; }
1516 virtual void setShaderSources (SourceCollections& programCollection) const;
1520 GeometryShaderExecutor::GeometryShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1521 : FragmentOutExecutor (shaderSpec, shaderType)
1525 GeometryShaderExecutor::~GeometryShaderExecutor (void)
1529 void GeometryShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1531 programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(m_shaderSpec.inputs, "a_", "vtx_out_"));
1533 programCollection.glslSources.add("geom") << glu::GeometrySource(generateGeometryShader(m_shaderSpec, "vtx_out_", "geom_out_"));
1535 /* \todo [2015-09-18 rsipka] set useIntOutputs parameter if needed. */
1536 programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(m_shaderSpec, false, m_outputLayout.locationMap, "geom_out_", "o_"));
1540 // FragmentShaderExecutor
1542 class FragmentShaderExecutor : public FragmentOutExecutor
1545 FragmentShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1546 virtual ~FragmentShaderExecutor (void);
1548 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst; }
1550 virtual void setShaderSources (SourceCollections& programCollection) const;
1554 FragmentShaderExecutor::FragmentShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1555 : FragmentOutExecutor (shaderSpec, shaderType)
1559 FragmentShaderExecutor::~FragmentShaderExecutor (void)
1563 void FragmentShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1565 programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(m_shaderSpec.inputs, "a_", "vtx_out_"));
1566 /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */
1567 programCollection.glslSources.add("frag") << glu::FragmentSource(generateFragmentShader(m_shaderSpec, false, m_outputLayout.locationMap, "vtx_out_", "o_"));
1570 // Shared utilities for compute and tess executors
1572 static deUint32 getVecStd430ByteAlignment (glu::DataType type)
1574 switch (glu::getDataTypeScalarSize(type))
1586 class BufferIoExecutor : public ShaderExecutor
1589 BufferIoExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1590 virtual ~BufferIoExecutor (void);
1592 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst; }
1597 INPUT_BUFFER_BINDING = 0,
1598 OUTPUT_BUFFER_BINDING = 1,
1601 void initBuffers (const Context& ctx, int numValues);
1602 VkBuffer getInputBuffer (void) const { return *m_inputBuffer; }
1603 VkBuffer getOutputBuffer (void) const { return *m_outputBuffer; }
1604 deUint32 getInputStride (void) const { return getLayoutStride(m_inputLayout); }
1605 deUint32 getOutputStride (void) const { return getLayoutStride(m_outputLayout); }
1607 void uploadInputBuffer (const Context& ctx, const void* const* inputPtrs, int numValues);
1608 void readOutputBuffer (const Context& ctx, void* const* outputPtrs, int numValues);
1610 static void declareBufferBlocks (std::ostream& src, const ShaderSpec& spec);
1611 static void generateExecBufferIo(std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName);
1614 Move<VkBuffer> m_inputBuffer;
1615 Move<VkBuffer> m_outputBuffer;
1622 deUint32 matrixStride;
1624 VarLayout (void) : offset(0), stride(0), matrixStride(0) {}
1627 static void computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout);
1628 static deUint32 getLayoutStride (const vector<VarLayout>& layout);
1630 static void copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1631 static void copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr);
1633 de::MovePtr<Allocation> m_inputAlloc;
1634 de::MovePtr<Allocation> m_outputAlloc;
1636 vector<VarLayout> m_inputLayout;
1637 vector<VarLayout> m_outputLayout;
1640 BufferIoExecutor::BufferIoExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1641 : ShaderExecutor (shaderSpec, shaderType)
1643 computeVarLayout(m_shaderSpec.inputs, &m_inputLayout);
1644 computeVarLayout(m_shaderSpec.outputs, &m_outputLayout);
1647 BufferIoExecutor::~BufferIoExecutor (void)
1651 inline deUint32 BufferIoExecutor::getLayoutStride (const vector<VarLayout>& layout)
1653 return layout.empty() ? 0 : layout[0].stride;
1656 void BufferIoExecutor::computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout)
1658 deUint32 maxAlignment = 0;
1659 deUint32 curOffset = 0;
1661 DE_ASSERT(layout != DE_NULL);
1662 DE_ASSERT(layout->empty());
1663 layout->resize(symbols.size());
1665 for (size_t varNdx = 0; varNdx < symbols.size(); varNdx++)
1667 const Symbol& symbol = symbols[varNdx];
1668 const glu::DataType basicType = symbol.varType.getBasicType();
1669 VarLayout& layoutEntry = (*layout)[varNdx];
1671 if (glu::isDataTypeScalarOrVector(basicType))
1673 const deUint32 alignment = getVecStd430ByteAlignment(basicType);
1674 const deUint32 size = (deUint32)glu::getDataTypeScalarSize(basicType) * (int)sizeof(deUint32);
1676 curOffset = (deUint32)deAlign32((int)curOffset, (int)alignment);
1677 maxAlignment = de::max(maxAlignment, alignment);
1679 layoutEntry.offset = curOffset;
1680 layoutEntry.matrixStride = 0;
1684 else if (glu::isDataTypeMatrix(basicType))
1686 const int numVecs = glu::getDataTypeMatrixNumColumns(basicType);
1687 const glu::DataType vecType = glu::getDataTypeFloatVec(glu::getDataTypeMatrixNumRows(basicType));
1688 const deUint32 vecAlignment = getVecStd430ByteAlignment(vecType);
1690 curOffset = (deUint32)deAlign32((int)curOffset, (int)vecAlignment);
1691 maxAlignment = de::max(maxAlignment, vecAlignment);
1693 layoutEntry.offset = curOffset;
1694 layoutEntry.matrixStride = vecAlignment;
1696 curOffset += vecAlignment*numVecs;
1703 const deUint32 totalSize = (deUint32)deAlign32(curOffset, maxAlignment);
1705 for (vector<VarLayout>::iterator varIter = layout->begin(); varIter != layout->end(); ++varIter)
1706 varIter->stride = totalSize;
1710 void BufferIoExecutor::declareBufferBlocks (std::ostream& src, const ShaderSpec& spec)
1713 if (!spec.inputs.empty())
1715 glu::StructType inputStruct("Inputs");
1716 for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1717 inputStruct.addMember(symIter->name.c_str(), symIter->varType);
1718 src << glu::declare(&inputStruct) << ";\n";
1723 glu::StructType outputStruct("Outputs");
1724 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1725 outputStruct.addMember(symIter->name.c_str(), symIter->varType);
1726 src << glu::declare(&outputStruct) << ";\n";
1731 if (!spec.inputs.empty())
1733 src << "layout(set = 0, binding = " << int(INPUT_BUFFER_BINDING) << ", std430) buffer InBuffer\n"
1735 << " Inputs inputs[];\n"
1739 src << "layout(set = 0, binding = " << int(OUTPUT_BUFFER_BINDING) << ", std430) buffer OutBuffer\n"
1741 << " Outputs outputs[];\n"
1746 void BufferIoExecutor::generateExecBufferIo (std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName)
1748 for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter)
1749 src << "\t" << glu::declare(symIter->varType, symIter->name) << " = inputs[" << invocationNdxName << "]." << symIter->name << ";\n";
1751 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1752 src << "\t" << glu::declare(symIter->varType, symIter->name) << ";\n";
1757 std::istringstream opSrc (spec.source);
1760 while (std::getline(opSrc, line))
1761 src << "\t" << line << "\n";
1765 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter)
1766 src << "\toutputs[" << invocationNdxName << "]." << symIter->name << " = " << symIter->name << ";\n";
1769 void BufferIoExecutor::copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1771 if (varType.isBasicType())
1773 const glu::DataType basicType = varType.getBasicType();
1774 const bool isMatrix = glu::isDataTypeMatrix(basicType);
1775 const int scalarSize = glu::getDataTypeScalarSize(basicType);
1776 const int numVecs = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1777 const int numComps = scalarSize / numVecs;
1779 for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1781 for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1783 const int srcOffset = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1784 const int dstOffset = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1785 const deUint8* srcPtr = (const deUint8*)srcBasePtr + srcOffset;
1786 deUint8* dstPtr = (deUint8*)dstBasePtr + dstOffset;
1788 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1793 throw tcu::InternalError("Unsupported type");
1796 void BufferIoExecutor::copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr)
1798 if (varType.isBasicType())
1800 const glu::DataType basicType = varType.getBasicType();
1801 const bool isMatrix = glu::isDataTypeMatrix(basicType);
1802 const int scalarSize = glu::getDataTypeScalarSize(basicType);
1803 const int numVecs = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1;
1804 const int numComps = scalarSize / numVecs;
1806 for (int elemNdx = 0; elemNdx < numValues; elemNdx++)
1808 for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
1810 const int srcOffset = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0);
1811 const int dstOffset = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps);
1812 const deUint8* srcPtr = (const deUint8*)srcBasePtr + srcOffset;
1813 deUint8* dstPtr = (deUint8*)dstBasePtr + dstOffset;
1815 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps);
1820 throw tcu::InternalError("Unsupported type");
1823 void BufferIoExecutor::uploadInputBuffer (const Context& ctx, const void* const* inputPtrs, int numValues)
1825 const VkDevice vkDevice = ctx.getDevice();
1826 const DeviceInterface& vk = ctx.getDeviceInterface();
1828 const deUint32 inputStride = getLayoutStride(m_inputLayout);
1829 const int inputBufferSize = inputStride * numValues;
1831 if (inputBufferSize == 0)
1832 return; // No inputs
1834 DE_ASSERT(m_shaderSpec.inputs.size() == m_inputLayout.size());
1835 for (size_t inputNdx = 0; inputNdx < m_shaderSpec.inputs.size(); ++inputNdx)
1837 const glu::VarType& varType = m_shaderSpec.inputs[inputNdx].varType;
1838 const VarLayout& layout = m_inputLayout[inputNdx];
1840 copyToBuffer(varType, layout, numValues, inputPtrs[inputNdx], m_inputAlloc->getHostPtr());
1843 flushMappedMemoryRange(vk, vkDevice, m_inputAlloc->getMemory(), m_inputAlloc->getOffset(), inputBufferSize);
1846 void BufferIoExecutor::readOutputBuffer (const Context& ctx, void* const* outputPtrs, int numValues)
1848 const VkDevice vkDevice = ctx.getDevice();
1849 const DeviceInterface& vk = ctx.getDeviceInterface();
1851 const deUint32 outputStride = getLayoutStride(m_outputLayout);
1852 const int outputBufferSize = numValues * outputStride;
1854 DE_ASSERT(outputBufferSize > 0); // At least some outputs are required.
1856 invalidateMappedMemoryRange(vk, vkDevice, m_outputAlloc->getMemory(), m_outputAlloc->getOffset(), outputBufferSize);
1858 DE_ASSERT(m_shaderSpec.outputs.size() == m_outputLayout.size());
1859 for (size_t outputNdx = 0; outputNdx < m_shaderSpec.outputs.size(); ++outputNdx)
1861 const glu::VarType& varType = m_shaderSpec.outputs[outputNdx].varType;
1862 const VarLayout& layout = m_outputLayout[outputNdx];
1864 copyFromBuffer(varType, layout, numValues, m_outputAlloc->getHostPtr(), outputPtrs[outputNdx]);
1868 void BufferIoExecutor::initBuffers (const Context& ctx, int numValues)
1870 const deUint32 inputStride = getLayoutStride(m_inputLayout);
1871 const deUint32 outputStride = getLayoutStride(m_outputLayout);
1872 // Avoid creating zero-sized buffer/memory
1873 const size_t inputBufferSize = numValues * inputStride ? (numValues * inputStride) : 1;
1874 const size_t outputBufferSize = numValues * outputStride;
1876 // Upload data to buffer
1877 const VkDevice vkDevice = ctx.getDevice();
1878 const DeviceInterface& vk = ctx.getDeviceInterface();
1879 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex();
1880 Allocator& memAlloc = ctx.getDefaultAllocator();
1882 const VkBufferCreateInfo inputBufferParams =
1884 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1885 DE_NULL, // const void* pNext;
1886 0u, // VkBufferCreateFlags flags;
1887 inputBufferSize, // VkDeviceSize size;
1888 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
1889 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1890 1u, // deUint32 queueFamilyCount;
1891 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1894 m_inputBuffer = createBuffer(vk, vkDevice, &inputBufferParams);
1895 m_inputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_inputBuffer), MemoryRequirement::HostVisible);
1897 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_inputBuffer, m_inputAlloc->getMemory(), m_inputAlloc->getOffset()));
1899 const VkBufferCreateInfo outputBufferParams =
1901 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1902 DE_NULL, // const void* pNext;
1903 0u, // VkBufferCreateFlags flags;
1904 outputBufferSize, // VkDeviceSize size;
1905 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
1906 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1907 1u, // deUint32 queueFamilyCount;
1908 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1911 m_outputBuffer = createBuffer(vk, vkDevice, &outputBufferParams);
1912 m_outputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_outputBuffer), MemoryRequirement::HostVisible);
1914 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_outputBuffer, m_outputAlloc->getMemory(), m_outputAlloc->getOffset()));
1917 // ComputeShaderExecutor
1919 class ComputeShaderExecutor : public BufferIoExecutor
1922 ComputeShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
1923 virtual ~ComputeShaderExecutor (void);
1925 virtual void setShaderSources (SourceCollections& programCollection) const;
1927 virtual void execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs);
1930 static std::string generateComputeShader (const ShaderSpec& spec);
1933 ComputeShaderExecutor::ComputeShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
1934 : BufferIoExecutor (shaderSpec, shaderType)
1938 ComputeShaderExecutor::~ComputeShaderExecutor (void)
1942 std::string ComputeShaderExecutor::generateComputeShader (const ShaderSpec& spec)
1944 std::ostringstream src;
1945 src << "#version 310 es\n"
1946 "#extension GL_ARB_separate_shader_objects : enable\n"
1947 "#extension GL_ARB_shading_language_420pack : enable\n";
1949 if (!spec.globalDeclarations.empty())
1950 src << spec.globalDeclarations << "\n";
1952 src << "layout(local_size_x = 1) in;\n"
1955 declareBufferBlocks(src, spec);
1957 src << "void main (void)\n"
1959 << " uint invocationNdx = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z\n"
1960 << " + gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n";
1962 generateExecBufferIo(src, spec, "invocationNdx");
1969 void ComputeShaderExecutor::setShaderSources (SourceCollections& programCollection) const
1971 programCollection.glslSources.add("compute") << glu::ComputeSource(generateComputeShader(m_shaderSpec));
1974 void ComputeShaderExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs)
1976 checkSupported(ctx, m_shaderType);
1978 const VkDevice vkDevice = ctx.getDevice();
1979 const DeviceInterface& vk = ctx.getDeviceInterface();
1980 const VkQueue queue = ctx.getUniversalQueue();
1981 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex();
1982 Allocator& memAlloc = ctx.getDefaultAllocator();
1984 Move<VkShaderModule> computeShaderModule;
1985 Move<VkPipeline> computePipeline;
1986 Move<VkPipelineLayout> pipelineLayout;
1987 Move<VkCommandPool> cmdPool;
1988 Move<VkDescriptorPool> descriptorPool;
1989 Move<VkDescriptorSetLayout> descriptorSetLayout;
1990 Move<VkDescriptorSet> descriptorSet;
1991 Move<VkFence> fence;
1993 initBuffers(ctx, numValues);
1995 // Setup input buffer & copy data
1996 uploadInputBuffer(ctx, inputs, numValues);
1998 // Create command pool
2000 const VkCommandPoolCreateInfo cmdPoolParams =
2002 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
2003 DE_NULL, // const void* pNext;
2004 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
2005 queueFamilyIndex // deUint32 queueFamilyIndex;
2008 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
2011 // Create command buffer
2012 const VkCommandBufferAllocateInfo cmdBufferParams =
2014 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
2015 DE_NULL, // const void* pNext;
2016 *cmdPool, // VkCmdPool cmdPool;
2017 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
2018 1u // deUint32 bufferCount;
2021 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
2023 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
2024 DE_NULL, // const void* pNext;
2025 0u, // VkCmdBufferOptimizeFlags flags;
2026 DE_NULL, // VkRenderPass renderPass;
2027 0u, // deUint32 subpass;
2028 DE_NULL, // VkFramebuffer framebuffer;
2029 VK_FALSE, // VkBool32 occlusionQueryEnable;
2030 (VkQueryControlFlags)0, // VkQueryControlFlags queryFlags;
2031 (VkQueryPipelineStatisticFlags)0 // VkQueryPipelineStatisticFlags pipelineStatistics;
2035 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
2036 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2037 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
2038 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2040 addUniforms(vkDevice, vk, queueFamilyIndex, memAlloc);
2042 descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
2043 descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2045 const VkDescriptorSetAllocateInfo allocInfo =
2047 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2051 &*descriptorSetLayout
2054 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2056 // Create pipeline layout
2058 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2060 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
2061 DE_NULL, // const void* pNext;
2062 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
2063 1u, // deUint32 CdescriptorSetCount;
2064 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
2065 0u, // deUint32 pushConstantRangeCount;
2066 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
2069 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2074 computeShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("compute"), 0);
2079 const VkPipelineShaderStageCreateInfo shaderStageParams[1] =
2082 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2083 DE_NULL, // const void* pNext;
2084 (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
2085 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagsBit stage;
2086 *computeShaderModule, // VkShaderModule shader;
2087 "main", // const char* pName;
2088 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2092 const VkComputePipelineCreateInfo computePipelineParams =
2094 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
2095 DE_NULL, // const void* pNext;
2096 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
2097 *shaderStageParams, // VkPipelineShaderStageCreateInfo cs;
2098 *pipelineLayout, // VkPipelineLayout layout;
2099 0u, // VkPipeline basePipelineHandle;
2100 0u, // int32_t basePipelineIndex;
2103 computePipeline = createComputePipeline(vk, vkDevice, DE_NULL, &computePipelineParams);
2108 const VkFenceCreateInfo fenceParams =
2110 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
2111 DE_NULL, // const void* pNext;
2112 0u // VkFenceCreateFlags flags;
2114 fence = createFence(vk, vkDevice, &fenceParams);
2118 const int maxValuesPerInvocation = ctx.getDeviceProperties().limits.maxComputeWorkGroupSize[0];
2120 const deUint32 inputStride = getInputStride();
2121 const deUint32 outputStride = getOutputStride();
2123 while (curOffset < numValues)
2125 Move<VkCommandBuffer> cmdBuffer;
2126 const int numToExec = de::min(maxValuesPerInvocation, numValues-curOffset);
2128 // Update descriptors
2130 DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2132 const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2134 *m_outputBuffer, // VkBuffer buffer;
2135 curOffset * outputStride, // VkDeviceSize offset;
2136 numToExec * outputStride // VkDeviceSize range;
2139 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2143 const VkDescriptorBufferInfo inputDescriptorBufferInfo =
2145 *m_inputBuffer, // VkBuffer buffer;
2146 curOffset * inputStride, // VkDeviceSize offset;
2147 numToExec * inputStride // VkDeviceSize range;
2150 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2153 uploadUniforms(descriptorSetUpdateBuilder, *descriptorSet);
2155 descriptorSetUpdateBuilder.update(vk, vkDevice);
2158 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
2159 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2160 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
2162 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
2164 vk.cmdDispatch(*cmdBuffer, numToExec, 1, 1);
2166 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2168 curOffset += numToExec;
2172 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2174 const VkSubmitInfo submitInfo =
2176 VK_STRUCTURE_TYPE_SUBMIT_INFO,
2179 (const VkSemaphore*)DE_NULL,
2183 (const VkSemaphore*)DE_NULL,
2186 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2187 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2192 readOutputBuffer(ctx, outputs, numValues);
2195 // Tessellation utils
2197 static std::string generateVertexShaderForTess (void)
2199 std::ostringstream src;
2200 src << "#version 310 es\n"
2201 << "void main (void)\n{\n"
2202 << " gl_Position = vec4(gl_VertexID/2, gl_VertexID%2, 0.0, 1.0);\n"
2208 class TessellationExecutor : public BufferIoExecutor
2211 TessellationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
2212 virtual ~TessellationExecutor (void);
2214 void renderTess (const Context& ctx, deUint32 vertexCount);
2217 TessellationExecutor::TessellationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2218 : BufferIoExecutor (shaderSpec, shaderType)
2222 TessellationExecutor::~TessellationExecutor (void)
2226 void TessellationExecutor::renderTess (const Context& ctx, deUint32 vertexCount)
2228 const size_t inputBufferSize = (vertexCount/2) * getInputStride();
2229 const VkDevice vkDevice = ctx.getDevice();
2230 const DeviceInterface& vk = ctx.getDeviceInterface();
2231 const VkQueue queue = ctx.getUniversalQueue();
2232 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex();
2233 Allocator& memAlloc = ctx.getDefaultAllocator();
2235 const tcu::IVec2 renderSize (DEFAULT_RENDER_WIDTH, DEFAULT_RENDER_HEIGHT);
2237 Move<VkImage> colorImage;
2238 de::MovePtr<Allocation> colorImageAlloc;
2239 VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
2240 Move<VkImageView> colorImageView;
2242 Move<VkRenderPass> renderPass;
2243 Move<VkFramebuffer> framebuffer;
2244 Move<VkPipelineLayout> pipelineLayout;
2245 Move<VkPipeline> graphicsPipeline;
2247 Move<VkShaderModule> vertexShaderModule;
2248 Move<VkShaderModule> tessControlShaderModule;
2249 Move<VkShaderModule> tessEvalShaderModule;
2250 Move<VkShaderModule> fragmentShaderModule;
2252 Move<VkCommandPool> cmdPool;
2253 Move<VkCommandBuffer> cmdBuffer;
2255 Move<VkFence> fence;
2257 Move<VkDescriptorPool> descriptorPool;
2258 Move<VkDescriptorSetLayout> descriptorSetLayout;
2259 Move<VkDescriptorSet> descriptorSet;
2261 // Create color image
2263 const VkImageCreateInfo colorImageParams =
2265 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2266 DE_NULL, // const void* pNext;
2267 0u, // VkImageCreateFlags flags;
2268 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2269 colorFormat, // VkFormat format;
2270 { renderSize.x(), renderSize.y(), 1u }, // VkExtent3D extent;
2271 1u, // deUint32 mipLevels;
2272 1u, // deUint32 arraySize;
2273 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2274 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2275 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
2276 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2277 1u, // deUint32 queueFamilyCount;
2278 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2279 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
2282 colorImage = createImage(vk, vkDevice, &colorImageParams);
2284 // Allocate and bind color image memory
2285 colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *colorImage), MemoryRequirement::Any);
2286 VK_CHECK(vk.bindImageMemory(vkDevice, *colorImage, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));
2289 // Create color attachment view
2291 const VkImageViewCreateInfo colorImageViewParams =
2293 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2294 DE_NULL, // const void* pNext;
2295 0u, // VkImageViewCreateFlags flags;
2296 *colorImage, // VkImage image;
2297 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2298 colorFormat, // VkFormat format;
2300 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
2301 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
2302 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
2303 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
2304 }, // VkComponentsMapping components;
2306 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2307 0u, // deUint32 baseMipLevel;
2308 1u, // deUint32 mipLevels;
2309 0u, // deUint32 baseArraylayer;
2310 1u // deUint32 layerCount;
2311 } // VkImageSubresourceRange subresourceRange;
2314 colorImageView = createImageView(vk, vkDevice, &colorImageViewParams);
2317 // Create render pass
2319 const VkAttachmentDescription colorAttachmentDescription =
2321 0u, // VkAttachmentDescriptorFlags flags;
2322 colorFormat, // VkFormat format;
2323 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2324 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
2325 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2326 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2327 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
2328 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
2329 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
2332 const VkAttachmentDescription attachments[1] =
2334 colorAttachmentDescription
2337 const VkAttachmentReference colorAttachmentReference =
2339 0u, // deUint32 attachment;
2340 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
2343 const VkSubpassDescription subpassDescription =
2345 0u, // VkSubpassDescriptionFlags flags;
2346 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
2347 0u, // deUint32 inputCount;
2348 DE_NULL, // const VkAttachmentReference* pInputAttachments;
2349 1u, // deUint32 colorCount;
2350 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
2351 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
2352 DE_NULL, // VkAttachmentReference depthStencilAttachment;
2353 0u, // deUint32 preserveCount;
2354 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
2357 const VkRenderPassCreateInfo renderPassParams =
2359 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
2360 DE_NULL, // const void* pNext;
2361 0u, // VkRenderPassCreateFlags flags;
2362 1u, // deUint32 attachmentCount;
2363 attachments, // const VkAttachmentDescription* pAttachments;
2364 1u, // deUint32 subpassCount;
2365 &subpassDescription, // const VkSubpassDescription* pSubpasses;
2366 0u, // deUint32 dependencyCount;
2367 DE_NULL // const VkSubpassDependency* pDependencies;
2370 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
2373 // Create framebuffer
2375 const VkFramebufferCreateInfo framebufferParams =
2377 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
2378 DE_NULL, // const void* pNext;
2379 0u, // VkFramebufferCreateFlags flags;
2380 *renderPass, // VkRenderPass renderPass;
2381 1u, // deUint32 attachmentCount;
2382 &*colorImageView, // const VkAttachmentBindInfo* pAttachments;
2383 (deUint32)renderSize.x(), // deUint32 width;
2384 (deUint32)renderSize.y(), // deUint32 height;
2385 1u // deUint32 layers;
2388 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
2391 // Create descriptors
2393 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2394 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2395 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
2396 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2398 addUniforms(vkDevice, vk, queueFamilyIndex, memAlloc);
2400 descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
2401 descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2403 const VkDescriptorSetAllocateInfo allocInfo =
2405 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2409 &*descriptorSetLayout
2412 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo);
2413 // Update descriptors
2415 DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
2416 const VkDescriptorBufferInfo outputDescriptorBufferInfo =
2418 *m_outputBuffer, // VkBuffer buffer;
2419 0u, // VkDeviceSize offset;
2420 VK_WHOLE_SIZE // VkDeviceSize range;
2423 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo);
2425 VkDescriptorBufferInfo inputDescriptorBufferInfo =
2427 0, // VkBuffer buffer;
2428 0u, // VkDeviceSize offset;
2429 VK_WHOLE_SIZE // VkDeviceSize range;
2431 if (inputBufferSize)
2433 inputDescriptorBufferInfo.buffer = *m_inputBuffer;
2435 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo);
2438 uploadUniforms(descriptorSetUpdateBuilder, *descriptorSet);
2440 descriptorSetUpdateBuilder.update(vk, vkDevice);
2444 // Create pipeline layout
2446 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
2448 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
2449 DE_NULL, // const void* pNext;
2450 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
2451 1u, // deUint32 descriptorSetCount;
2452 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
2453 0u, // deUint32 pushConstantRangeCount;
2454 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
2457 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2460 // Create shader modules
2462 vertexShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("vert"), 0);
2463 tessControlShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("tess_control"), 0);
2464 tessEvalShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("tess_eval"), 0);
2465 fragmentShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("frag"), 0);
2470 const VkPipelineShaderStageCreateInfo shaderStageParams[4] =
2473 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2474 DE_NULL, // const void* pNext;
2475 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2476 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBit stage;
2477 *vertexShaderModule, // VkShaderModule shader;
2478 "main", // const char* pName;
2479 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2482 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2483 DE_NULL, // const void* pNext;
2484 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2485 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, // VkShaderStageFlagBit stage;
2486 *tessControlShaderModule, // VkShaderModule shader;
2487 "main", // const char* pName;
2488 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2491 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2492 DE_NULL, // const void* pNext;
2493 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2494 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, // VkShaderStageFlagBit stage;
2495 *tessEvalShaderModule, // VkShaderModule shader;
2496 "main", // const char* pName;
2497 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2500 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2501 DE_NULL, // const void* pNext;
2502 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2503 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBit stage;
2504 *fragmentShaderModule, // VkShaderModule shader;
2505 "main", // const char* pName;
2506 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
2510 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
2512 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
2513 DE_NULL, // const void* pNext;
2514 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
2515 0u, // deUint32 bindingCount;
2516 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
2517 0u, // deUint32 attributeCount;
2518 DE_NULL, // const VkVertexInputAttributeDescription* pvertexAttributeDescriptions;
2521 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
2523 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
2524 DE_NULL, // const void* pNext;
2525 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
2526 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, // VkPrimitiveTopology topology;
2527 DE_FALSE // VkBool32 primitiveRestartEnable;
2530 struct VkPipelineTessellationStateCreateInfo tessellationStateParams =
2532 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
2533 DE_NULL, // const void* pNext;
2534 (VkPipelineTesselationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags;
2535 1 // uint32_t patchControlPoints;
2538 const VkViewport viewport =
2540 0.0f, // float originX;
2541 0.0f, // float originY;
2542 (float)renderSize.x(), // float width;
2543 (float)renderSize.y(), // float height;
2544 0.0f, // float minDepth;
2545 1.0f // float maxDepth;
2548 const VkRect2D scissor =
2553 }, // VkOffset2D offset;
2555 renderSize.x(), // deUint32 width;
2556 renderSize.y(), // deUint32 height;
2557 }, // VkExtent2D extent;
2560 const VkPipelineViewportStateCreateInfo viewportStateParams =
2562 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
2563 DE_NULL, // const void* pNext;
2564 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewPortStateCreateFlags flags;
2565 1u, // deUint32 viewportCount;
2566 &viewport, // const VkViewport* pViewports;
2567 1u, // deUint32 scissorsCount;
2568 &scissor // const VkRect2D* pScissors;
2571 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
2573 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
2574 DE_NULL, // const void* pNext;
2575 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStageCreateFlags flags;
2576 VK_FALSE, // VkBool32 depthClipEnable;
2577 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
2578 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
2579 VK_CULL_MODE_NONE, // VkCullMode cullMode;
2580 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
2581 VK_FALSE, // VkBool32 depthBiasEnable;
2582 0.0f, // float depthBias;
2583 0.0f, // float depthBiasClamp;
2584 0.0f, // float slopeScaledDepthBias;
2585 1.0f // float lineWidth;
2588 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
2590 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
2591 DE_NULL, // const void* pNext;
2592 0u, // VkPipelineMultisampleStateCreateFlags flags;
2593 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
2594 VK_FALSE, // VkBool32 sampleShadingEnable;
2595 0.0f, // float minSampleShading;
2596 DE_NULL, // const VkSampleMask* pSampleMask;
2597 VK_FALSE, // VkBool32 alphaToCoverageEnable;
2598 VK_FALSE // VkBool32 alphaToOneEnable;
2601 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
2603 VK_FALSE, // VkBool32 blendEnable;
2604 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcBlendColor;
2605 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destBlendColor;
2606 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
2607 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcBlendAlpha;
2608 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destBlendAlpha;
2609 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
2610 (VK_COLOR_COMPONENT_R_BIT |
2611 VK_COLOR_COMPONENT_G_BIT |
2612 VK_COLOR_COMPONENT_B_BIT |
2613 VK_COLOR_COMPONENT_A_BIT) // VkColorComponentFlags colorWriteMask;
2616 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
2618 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
2619 DE_NULL, // const void* pNext;
2620 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags
2621 VK_FALSE, // VkBool32 logicOpEnable;
2622 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
2623 1u, // deUint32 attachmentCount;
2624 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
2625 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConst[4];
2628 const VkPipelineDynamicStateCreateInfo dynamicStateInfo =
2630 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
2631 DE_NULL, // const void* pNext;
2632 (VkPipelineDynamicStateCreateFlags)0, // VkPipelineDynamicStateCreateFlags flags;
2633 0u, // deUint32 dynamicStateCount;
2634 DE_NULL // const VkDynamicState* pDynamicStates;
2637 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
2639 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
2640 DE_NULL, // const void* pNext;
2641 0u, // VkPipelineCreateFlags flags;
2642 4u, // deUint32 stageCount;
2643 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages;
2644 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
2645 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
2646 &tessellationStateParams, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
2647 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
2648 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
2649 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
2650 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
2651 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
2652 &dynamicStateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
2653 *pipelineLayout, // VkPipelineLayout layout;
2654 *renderPass, // VkRenderPass renderPass;
2655 0u, // deUint32 subpass;
2656 0u, // VkPipeline basePipelineHandle;
2657 0u // deInt32 basePipelineIndex;
2660 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
2663 // Create command pool
2665 const VkCommandPoolCreateInfo cmdPoolParams =
2667 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
2668 DE_NULL, // const void* pNext;
2669 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
2670 queueFamilyIndex, // deUint32 queueFamilyIndex;
2673 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
2676 // Create command buffer
2678 const VkCommandBufferAllocateInfo cmdBufferParams =
2680 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
2681 DE_NULL, // const void* pNext;
2682 *cmdPool, // VkCmdPool cmdPool;
2683 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level;
2684 1u // uint32_t bufferCount;
2687 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
2689 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
2690 DE_NULL, // const void* pNext;
2691 0u, // VkCmdBufferOptimizeFlags flags;
2692 DE_NULL, // VkRenderPass renderPass;
2693 0u, // deUint32 subpass;
2694 DE_NULL, // VkFramebuffer framebuffer;
2695 VK_FALSE, //VkBool32 occlusionQueryEnable;
2696 (VkQueryControlFlags)0u, // VkQueryControlFlags queryFlags;
2697 (VkQueryPipelineStatisticFlags)0u // VkQueryPipelineStatisticFlags pipelineStatistics;
2701 const VkClearValue clearValues[1] =
2703 getDefaultClearColor()
2706 const VkRenderPassBeginInfo renderPassBeginInfo =
2708 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
2709 DE_NULL, // const void* pNext;
2710 *renderPass, // VkRenderPass renderPass;
2711 *framebuffer, // VkFramebuffer framebuffer;
2712 { { 0, 0 }, { renderSize.x(), renderSize.y() } }, // VkRect2D renderArea;
2713 1, // deUint32 attachmentCount;
2714 clearValues // const VkClearValue* pClearValues;
2717 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams);
2719 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
2721 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2723 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
2725 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
2727 vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
2729 vk.cmdEndRenderPass(*cmdBuffer);
2730 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
2735 const VkFenceCreateInfo fenceParams =
2737 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
2738 DE_NULL, // const void* pNext;
2739 0u // VkFenceCreateFlags flags;
2741 fence = createFence(vk, vkDevice, &fenceParams);
2746 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
2747 const VkSubmitInfo submitInfo =
2749 VK_STRUCTURE_TYPE_SUBMIT_INFO,
2752 (const VkSemaphore*)0,
2756 (const VkSemaphore*)0,
2758 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
2759 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/));
2763 // TessControlExecutor
2765 class TessControlExecutor : public TessellationExecutor
2768 TessControlExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
2769 virtual ~TessControlExecutor (void);
2771 virtual void setShaderSources (SourceCollections& programCollection) const;
2773 virtual void execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs);
2776 static std::string generateTessControlShader (const ShaderSpec& shaderSpec);
2779 TessControlExecutor::TessControlExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2780 : TessellationExecutor (shaderSpec, shaderType)
2784 TessControlExecutor::~TessControlExecutor (void)
2788 std::string TessControlExecutor::generateTessControlShader (const ShaderSpec& shaderSpec)
2790 std::ostringstream src;
2791 src << "#version 310 es\n"
2792 "#extension GL_EXT_tessellation_shader : require\n\n"
2793 "#extension GL_ARB_separate_shader_objects : enable\n"
2794 "#extension GL_ARB_shading_language_420pack : enable\n";
2796 if (!shaderSpec.globalDeclarations.empty())
2797 src << shaderSpec.globalDeclarations << "\n";
2799 src << "\nlayout(vertices = 1) out;\n\n";
2801 declareBufferBlocks(src, shaderSpec);
2803 src << "void main (void)\n{\n";
2805 for (int ndx = 0; ndx < 2; ndx++)
2806 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2808 for (int ndx = 0; ndx < 4; ndx++)
2809 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2812 << "\thighp uint invocationId = uint(gl_PrimitiveID);\n";
2814 generateExecBufferIo(src, shaderSpec, "invocationId");
2821 static std::string generateEmptyTessEvalShader ()
2823 std::ostringstream src;
2825 src << "#version 310 es\n"
2826 "#extension GL_EXT_tessellation_shader : require\n\n"
2827 "#extension GL_ARB_separate_shader_objects : enable\n"
2828 "#extension GL_ARB_shading_language_420pack : enable\n";
2830 src << "layout(triangles, ccw) in;\n";
2832 src << "\nvoid main (void)\n{\n"
2833 << "\tgl_Position = vec4(gl_TessCoord.xy, 0.0, 1.0);\n"
2839 void TessControlExecutor::setShaderSources (SourceCollections& programCollection) const
2841 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess());
2842 programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generateTessControlShader(m_shaderSpec));
2843 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateEmptyTessEvalShader());
2844 programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource());
2847 void TessControlExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs)
2849 checkSupported(ctx, m_shaderType);
2851 initBuffers(ctx, numValues);
2853 // Setup input buffer & copy data
2854 uploadInputBuffer(ctx, inputs, numValues);
2856 renderTess(ctx, 3 * numValues);
2859 readOutputBuffer(ctx, outputs, numValues);
2862 // TessEvaluationExecutor
2864 class TessEvaluationExecutor : public TessellationExecutor
2867 TessEvaluationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType);
2868 virtual ~TessEvaluationExecutor (void);
2870 virtual void setShaderSources (SourceCollections& programCollection) const;
2872 virtual void execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs);
2875 static std::string generateTessEvalShader (const ShaderSpec& shaderSpec);
2878 TessEvaluationExecutor::TessEvaluationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2879 : TessellationExecutor (shaderSpec, shaderType)
2883 TessEvaluationExecutor::~TessEvaluationExecutor (void)
2887 static std::string generatePassthroughTessControlShader (void)
2889 std::ostringstream src;
2891 src << "#version 310 es\n"
2892 "#extension GL_EXT_tessellation_shader : require\n\n"
2893 "#extension GL_ARB_separate_shader_objects : enable\n"
2894 "#extension GL_ARB_shading_language_420pack : enable\n";
2896 src << "layout(vertices = 1) out;\n\n";
2898 src << "void main (void)\n{\n";
2900 for (int ndx = 0; ndx < 2; ndx++)
2901 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n";
2903 for (int ndx = 0; ndx < 4; ndx++)
2904 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n";
2911 std::string TessEvaluationExecutor::generateTessEvalShader (const ShaderSpec& shaderSpec)
2913 std::ostringstream src;
2915 src << "#version 310 es\n"
2916 "#extension GL_EXT_tessellation_shader : require\n\n"
2917 "#extension GL_ARB_separate_shader_objects : enable\n"
2918 "#extension GL_ARB_shading_language_420pack : enable\n";
2920 if (!shaderSpec.globalDeclarations.empty())
2921 src << shaderSpec.globalDeclarations << "\n";
2925 src << "layout(isolines, equal_spacing) in;\n\n";
2927 declareBufferBlocks(src, shaderSpec);
2929 src << "void main (void)\n{\n"
2930 << "\tgl_Position = vec4(gl_TessCoord.x, 0.0, 0.0, 1.0);\n"
2931 << "\thighp uint invocationId = uint(gl_PrimitiveID) + (gl_TessCoord.x > 0.5 ? 1u : 0u);\n";
2933 generateExecBufferIo(src, shaderSpec, "invocationId");
2940 void TessEvaluationExecutor::setShaderSources (SourceCollections& programCollection) const
2942 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess());
2943 programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generatePassthroughTessControlShader());
2944 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateTessEvalShader(m_shaderSpec));
2945 programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource());
2948 void TessEvaluationExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs)
2950 checkSupported(ctx, m_shaderType);
2952 const int alignedValues = deAlign32(numValues, 2);
2954 // Initialize buffers with aligned value count to make room for padding
2955 initBuffers(ctx, alignedValues);
2957 // Setup input buffer & copy data
2958 uploadInputBuffer(ctx, inputs, numValues);
2960 renderTess(ctx, 2 * numValues);
2963 readOutputBuffer(ctx, outputs, numValues);
2970 ShaderExecutor::ShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType)
2971 : m_shaderSpec (shaderSpec)
2972 , m_shaderType (shaderType)
2976 ShaderExecutor::~ShaderExecutor (void)
2982 ShaderExecutor* createExecutor (glu::ShaderType shaderType, const ShaderSpec& shaderSpec)
2986 case glu::SHADERTYPE_VERTEX: return new VertexShaderExecutor (shaderSpec, shaderType);
2987 case glu::SHADERTYPE_TESSELLATION_CONTROL: return new TessControlExecutor (shaderSpec, shaderType);
2988 case glu::SHADERTYPE_TESSELLATION_EVALUATION: return new TessEvaluationExecutor (shaderSpec, shaderType);
2989 case glu::SHADERTYPE_GEOMETRY: return new GeometryShaderExecutor (shaderSpec, shaderType);
2990 case glu::SHADERTYPE_FRAGMENT: return new FragmentShaderExecutor (shaderSpec, shaderType);
2991 case glu::SHADERTYPE_COMPUTE: return new ComputeShaderExecutor (shaderSpec, shaderType);
2993 throw tcu::InternalError("Unsupported shader type");
2997 void ShaderExecutor::setupUniformData (const VkDevice& vkDevice,
2998 const DeviceInterface& vk,
2999 const deUint32 queueFamilyIndex,
3000 Allocator& memAlloc,
3001 deUint32 bindingLocation,
3002 VkDescriptorType descriptorType,
3004 const void* dataPtr)
3006 DE_ASSERT(descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
3008 VkImageUsageFlags usage = descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
3010 const VkBufferCreateInfo uniformBufferParams =
3012 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
3013 DE_NULL, // const void* pNext;
3014 0u, // VkBufferCreateFlags flags;
3015 size, // VkDeviceSize size;
3016 usage, // VkBufferUsageFlags usage;
3017 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3018 1u, // deUint32 queueFamilyIndexCount;
3019 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
3022 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &uniformBufferParams);
3023 de::MovePtr<Allocation> alloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
3024 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset()));
3026 deMemcpy(alloc->getHostPtr(), dataPtr, size);
3027 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), size);
3029 de::MovePtr<BufferUniform> uniformInfo(new BufferUniform());
3030 uniformInfo->type = descriptorType;
3031 uniformInfo->descriptor = makeDescriptorBufferInfo(*buffer, 0u, size);
3032 uniformInfo->location = bindingLocation;
3033 uniformInfo->buffer = VkBufferSp(new Unique<VkBuffer>(buffer));
3034 uniformInfo->alloc = AllocationSp(alloc.release());
3036 m_descriptorSetLayoutBuilder.addSingleBinding(descriptorType, VK_SHADER_STAGE_ALL);
3037 m_descriptorPoolBuilder.addType(descriptorType);
3039 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniformInfo)));
3042 void ShaderExecutor::setupSamplerData (const VkDevice& vkDevice,
3043 const DeviceInterface& vk,
3044 const deUint32 queueFamilyIndex,
3045 Allocator& memAlloc,
3046 deUint32 bindingLocation,
3047 deUint32 numSamplers,
3048 const tcu::Sampler& refSampler,
3049 const tcu::TextureFormat& texFormat,
3050 const tcu::IVec3& texSize,
3051 VkImageType imageType,
3052 VkImageViewType imageViewType,
3055 DE_ASSERT(numSamplers > 0);
3057 std::vector<VkSampler> vkSamplers;
3058 de::MovePtr<SamplerArrayUniform> samplers (new SamplerArrayUniform());
3060 samplers->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
3061 samplers->location = bindingLocation;
3063 for (deUint32 ndx = 0; ndx < numSamplers; ++ndx)
3065 const int offset = ndx * texSize.x() * texSize.y() * texSize.z() * texFormat.getPixelSize();
3066 const void* samplerData = ((deUint8*)data) + offset;
3067 de::MovePtr<SamplerUniform> uniform = createSamplerUniform(vkDevice, vk, queueFamilyIndex, memAlloc, bindingLocation, refSampler, texFormat, texSize, imageType, imageViewType, samplerData);
3069 vkSamplers.push_back(uniform->sampler.get()->get());
3071 samplers->uniforms.push_back(SamplerUniformSp(new de::UniquePtr<SamplerUniform>(uniform)));
3074 m_descriptorSetLayoutBuilder.addArraySamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, numSamplers, VK_SHADER_STAGE_ALL, &vkSamplers[0]);
3075 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, numSamplers);
3077 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(samplers)));
3080 void ShaderExecutor::addUniforms (const VkDevice& vkDevice, const DeviceInterface& vk, const deUint32 queueFamilyIndex, Allocator& memAlloc)
3082 if (!m_uniformSetup)
3085 for (std::vector<UniformDataSp>::const_iterator it = m_uniformSetup->uniforms().begin(); it != m_uniformSetup->uniforms().end(); ++it)
3087 const UniformDataBase* uniformData = it->get()->get();
3088 uniformData->setup(*this, vkDevice, vk, queueFamilyIndex, memAlloc);
3092 void ShaderExecutor::uploadUniforms (DescriptorSetUpdateBuilder& descriptorSetUpdateBuilder, VkDescriptorSet descriptorSet)
3094 for (std::vector<UniformInfoSp>::const_iterator it = m_uniformInfos.begin(); it != m_uniformInfos.end(); ++it)
3096 const UniformInfo* uniformInfo = it->get()->get();
3098 if (uniformInfo->isSamplerArray())
3100 const SamplerArrayUniform* arrayInfo = static_cast<const SamplerArrayUniform*>(uniformInfo);
3101 std::vector<VkDescriptorImageInfo> descriptors;
3103 for (std::vector<SamplerUniformSp>::const_iterator ait = arrayInfo->uniforms.begin(); ait != arrayInfo->uniforms.end(); ++ait)
3105 descriptors.push_back(ait->get()->get()->descriptor);
3108 descriptorSetUpdateBuilder.writeArray(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(uniformInfo->location), uniformInfo->type, (deUint32)descriptors.size(), &descriptors[0]);
3110 else if (uniformInfo->isBufferUniform())
3112 const BufferUniform* bufferUniform = static_cast<const BufferUniform*>(uniformInfo);
3113 descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(bufferUniform->location), bufferUniform->type, &bufferUniform->descriptor);
3115 else if (uniformInfo->isSamplerUniform())
3117 const SamplerUniform* samplerUniform = static_cast<const SamplerUniform*>(uniformInfo);
3118 descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(samplerUniform->location), samplerUniform->type, &samplerUniform->descriptor);
3123 Move<VkImage> ShaderExecutor::createCombinedImage (const VkDevice& vkDevice,
3124 const DeviceInterface& vk,
3125 const deUint32 queueFamilyIndex,
3126 const tcu::IVec3& texSize,
3127 const VkFormat format,
3128 const VkImageType imageType,
3129 const VkImageViewType imageViewType,
3130 const VkImageUsageFlags usage,
3131 const VkImageTiling tiling)
3133 const bool isCube = imageViewType == vk::VK_IMAGE_VIEW_TYPE_CUBE;
3134 const VkImageCreateFlags flags = isCube ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlags)0;
3135 const deUint32 arraySize = isCube ? 6u : 1u;
3137 const VkImageCreateInfo imageCreateInfo =
3139 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3140 DE_NULL, // const void* pnext;
3141 flags, // VkImageCreateFlags flags;
3142 imageType, // VkImageType imageType;
3143 format, // VkFormat format;
3144 { texSize.x(), texSize.y(), texSize.z() }, // VkExtend3D extent;
3145 1u, // deUint32 mipLevels;
3146 arraySize, // deUint32 arraySize;
3147 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
3148 tiling, // VkImageTiling tiling;
3149 usage, // VkImageUsageFlags usage;
3150 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3151 1u, // deuint32 queueFamilyCount;
3152 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
3153 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
3156 Move<VkImage> vkTexture = createImage(vk, vkDevice, &imageCreateInfo);
3160 de::MovePtr<Allocation> ShaderExecutor::uploadImage (const VkDevice& vkDevice,
3161 const DeviceInterface& vk,
3162 Allocator& memAlloc,
3163 const tcu::TextureFormat& texFormat,
3164 const tcu::IVec3& texSize,
3166 const VkImage& vkTexture,
3167 const VkImageAspectFlags aspectMask)
3169 de::MovePtr<Allocation> allocation = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, vkTexture), MemoryRequirement::HostVisible);
3170 VK_CHECK(vk.bindImageMemory(vkDevice, vkTexture, allocation->getMemory(), allocation->getOffset()));
3172 const VkImageSubresource subres =
3174 aspectMask, // VkImageAspectFlags aspectMask;
3175 0u, // deUint32 mipLevel;
3176 0u // deUint32 arraySlice
3179 VkSubresourceLayout layout;
3180 vk.getImageSubresourceLayout(vkDevice, vkTexture, &subres, &layout);
3182 tcu::ConstPixelBufferAccess access (texFormat, texSize, data);
3183 tcu::PixelBufferAccess destAccess (texFormat, texSize, allocation->getHostPtr());
3185 tcu::copy(destAccess, access);
3187 flushMappedMemoryRange(vk, vkDevice, allocation->getMemory(), allocation, layout.size);
3192 de::MovePtr<ShaderExecutor::SamplerUniform> ShaderExecutor::createSamplerUniform (const VkDevice& vkDevice,
3193 const DeviceInterface& vk,
3194 const deUint32 queueFamilyIndex,
3195 Allocator& memAlloc,
3196 deUint32 bindingLocation,
3197 const tcu::Sampler& refSampler,
3198 const tcu::TextureFormat& texFormat,
3199 const tcu::IVec3& texSize,
3200 VkImageType imageType,
3201 VkImageViewType imageViewType,
3204 const VkFormat format = mapTextureFormat(texFormat);
3205 const bool isCube = imageViewType == VK_IMAGE_VIEW_TYPE_CUBE;
3206 const bool isShadowSampler = texFormat == tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
3207 const VkImageUsageFlags imageUsage = isShadowSampler ? (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) : VK_IMAGE_USAGE_SAMPLED_BIT;
3208 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
3209 const deUint32 arraySize = isCube ? 6u : 1u;
3210 Move<VkImage> vkTexture;
3211 de::MovePtr<Allocation> allocation;
3213 vkTexture = createCombinedImage(vkDevice, vk, queueFamilyIndex, texSize, format, imageType, imageViewType, imageUsage, VK_IMAGE_TILING_OPTIMAL);
3214 allocation = uploadImage(vkDevice, vk, memAlloc, texFormat, texSize, data, *vkTexture, aspectMask);
3217 const bool compareEnabled = (refSampler.compare != tcu::Sampler::COMPAREMODE_NONE);
3218 const VkSamplerCreateInfo samplerParams =
3220 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
3221 DE_NULL, // const void* pNext;
3222 VkSamplerCreateFlags(0u), // VkSamplerCreateFlags flags;
3223 mapFilterMode(refSampler.magFilter), // VkTexFilter magFilter;
3224 mapFilterMode(refSampler.minFilter), // VkTexFilter minFilter;
3225 mapMipmapMode(refSampler.minFilter), // VkTexMipmapMode mipMode;
3226 mapWrapMode(refSampler.wrapS), // VkTexAddressMode addressModeU;
3227 mapWrapMode(refSampler.wrapT), // VkTexAddressMode addressModeV;
3228 mapWrapMode(refSampler.wrapR), // VkTexAddressMode addressModeW;
3229 refSampler.lodThreshold, // float mipLodBias;
3230 1, // float maxAnisotropy;
3231 compareEnabled, // VkBool32 compareEnable;
3232 mapCompareMode(refSampler.compare), // VkCompareOp compareOp;
3233 0.0f, // float minLod;
3234 0.0f, // float maxLod;
3235 VK_BORDER_COLOR_INT_OPAQUE_WHITE, // VkBorderColor boderColor;
3236 VK_FALSE, // VkBool32 unnormalizerdCoordinates;
3239 Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams);
3241 const VkImageViewCreateInfo viewParams =
3243 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
3244 NULL, // const voide* pNexŧ;
3245 0u, // VkImageViewCreateFlags flags;
3246 *vkTexture, // VkImage image;
3247 imageViewType, // VkImageViewType viewType;
3248 format, // VkFormat format;
3250 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
3251 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
3252 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
3253 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
3254 }, // VkComponentMapping components;
3256 aspectMask, // VkImageAspectFlags aspectMask;
3257 0, // deUint32 baseMipLevel;
3258 1, // deUint32 mipLevels;
3259 0, // deUint32 baseArraySlice;
3260 arraySize // deUint32 arraySize;
3261 } // VkImageSubresourceRange subresourceRange;
3264 Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams);
3266 const VkDescriptorImageInfo descriptor =
3268 sampler.get(), // VkSampler sampler;
3269 imageView.get(), // VkImageView imageView;
3270 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
3273 de::MovePtr<SamplerUniform> uniform(new SamplerUniform());
3274 uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
3275 uniform->descriptor = descriptor;
3276 uniform->location = bindingLocation;
3277 uniform->image = VkImageSp(new Unique<VkImage>(vkTexture));
3278 uniform->imageView = VkImageViewSp(new Unique<VkImageView>(imageView));
3279 uniform->sampler = VkSamplerSp(new Unique<VkSampler>(sampler));
3280 uniform->alloc = AllocationSp(allocation.release());
3285 SamplerUniformData::SamplerUniformData (deUint32 bindingLocation,
3286 deUint32 numSamplers,
3287 const tcu::Sampler& refSampler,
3288 const tcu::TextureFormat& texFormat,
3289 const tcu::IVec3& texSize,
3290 VkImageType imageType,
3291 VkImageViewType imageViewType,
3293 : UniformDataBase (bindingLocation)
3294 , m_numSamplers (numSamplers)
3295 , m_refSampler (refSampler)
3296 , m_texFormat (texFormat)
3297 , m_texSize (texSize)
3298 , m_imageType (imageType)
3299 , m_imageViewType (imageViewType)
3304 SamplerUniformData::~SamplerUniformData (void)
3308 void SamplerUniformData::setup (ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const deUint32 queueFamilyIndex, Allocator& memAlloc) const
3310 executor.setupSamplerData(vkDevice, vk, queueFamilyIndex, memAlloc, m_bindingLocation, m_numSamplers, m_refSampler, m_texFormat, m_texSize, m_imageType, m_imageViewType, m_data);