1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2015 The Khronos Group Inc. 6 * Copyright (c) 2015 Samsung Electronics Co., Ltd. 7 * Copyright (c) 2016 The Android Open Source Project 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 *//*! 22 * \file 23 * \brief Vulkan ShaderExecutor 24 *//*--------------------------------------------------------------------*/ 25 26#include "vktShaderExecutor.hpp" 27#include <map> 28#include <sstream> 29#include <iostream> 30 31#include "tcuVector.hpp" 32#include "tcuTestLog.hpp" 33#include "tcuFormatUtil.hpp" 34#include "tcuTextureUtil.hpp" 35#include "deUniquePtr.hpp" 36#include "deStringUtil.hpp" 37#include "deSharedPtr.hpp" 38 39#include "vkMemUtil.hpp" 40#include "vkRef.hpp" 41#include "vkPlatform.hpp" 42#include "vkPrograms.hpp" 43#include "vkStrUtil.hpp" 44#include "vkRefUtil.hpp" 45#include "vkTypeUtil.hpp" 46#include "vkQueryUtil.hpp" 47#include "vkDeviceUtil.hpp" 48#include "vkImageUtil.hpp" 49 50#include "gluShaderUtil.hpp" 51 52using std::vector; 53using namespace vk; 54 55namespace vkt 56{ 57namespace shaderexecutor 58{ 59namespace 60{ 61 62enum 63{ 64 DEFAULT_RENDER_WIDTH = 100, 65 DEFAULT_RENDER_HEIGHT = 100, 66}; 67 68// Shader utilities 69 70static VkClearValue getDefaultClearColor (void) 71{ 72 return makeClearValueColorF32(0.125f, 0.25f, 0.5f, 1.0f); 73} 74 75static void checkSupported (const Context& ctx, glu::ShaderType shaderType) 76{ 77 const VkPhysicalDeviceFeatures& features = ctx.getDeviceFeatures(); 78 79 if (shaderType == glu::SHADERTYPE_GEOMETRY && !features.geometryShader) 80 TCU_THROW(NotSupportedError, "Geometry shader type not supported by device"); 81 else if (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL && !features.tessellationShader) 82 TCU_THROW(NotSupportedError, "Tessellation shader type not supported by device"); 83 else if (shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION && !features.tessellationShader) 84 TCU_THROW(NotSupportedError, "Tessellation shader type not supported by device"); 85} 86 87static std::string generateEmptyFragmentSource () 88{ 89 std::ostringstream src; 90 91 src << "#version 310 es\n" 92 "layout(location=0) out highp vec4 o_color;\n"; 93 94 src << "void main (void)\n{\n"; 95 src << " o_color = vec4(0.0);\n"; 96 src << "}\n"; 97 98 return src.str(); 99} 100 101static std::string generatePassthroughVertexShader (const std::vector<Symbol>& inputs, const char* inputPrefix, const char* outputPrefix) 102{ 103 104 std::ostringstream src; 105 int location = 0; 106 107 src << "#version 310 es\n" 108 "layout(location = " << location << ") in highp vec4 a_position;\n"; 109 110 for (vector<Symbol>::const_iterator input = inputs.begin(); input != inputs.end(); ++input) 111 { 112 location++; 113 src << "layout(location = "<< location << ") in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n" 114 << "layout(location = " << location - 1 << ") flat out " << glu::declare(input->varType, outputPrefix + input->name) << ";\n"; 115 } 116 117 src << "\nvoid main (void)\n{\n" 118 << " gl_Position = a_position;\n" 119 << " gl_PointSize = 1.0;\n"; 120 121 for (vector<Symbol>::const_iterator input = inputs.begin(); input != inputs.end(); ++input) 122 src << "\t" << outputPrefix << input->name << " = " << inputPrefix << input->name << ";\n"; 123 124 src << "}\n"; 125 126 return src.str(); 127} 128 129static std::string generateVertexShader (const ShaderSpec& shaderSpec, const std::string& inputPrefix, const std::string& outputPrefix) 130{ 131 DE_ASSERT(!inputPrefix.empty() && !outputPrefix.empty()); 132 133 std::ostringstream src; 134 135 src << "#version 310 es\n"; 136 137 if (!shaderSpec.globalDeclarations.empty()) 138 src << shaderSpec.globalDeclarations << "\n"; 139 140 src << "layout(location = 0) in highp vec4 a_position;\n"; 141 142 int locationNumber = 1; 143 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber) 144 src << "layout(location = " << locationNumber << ") in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n"; 145 146 locationNumber = 0; 147 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber) 148 { 149 DE_ASSERT(output->varType.isBasicType()); 150 151 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType())) 152 { 153 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType()); 154 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT; 155 const glu::VarType intType (intBaseType, glu::PRECISION_HIGHP); 156 157 src << "layout(location = " << locationNumber << ") flat out " << glu::declare(intType, outputPrefix + output->name) << ";\n"; 158 } 159 else 160 src << "layout(location = " << locationNumber << ") flat out " << glu::declare(output->varType, outputPrefix + output->name) << ";\n"; 161 } 162 163 src << "\n" 164 << "void main (void)\n" 165 << "{\n" 166 << " gl_Position = a_position;\n" 167 << " gl_PointSize = 1.0;\n"; 168 169 // Declare & fetch local input variables 170 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input) 171 src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << ";\n"; 172 173 // Declare local output variables 174 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output) 175 src << "\t" << glu::declare(output->varType, output->name) << ";\n"; 176 177 // Operation - indented to correct level. 178 { 179 std::istringstream opSrc (shaderSpec.source); 180 std::string line; 181 182 while (std::getline(opSrc, line)) 183 src << "\t" << line << "\n"; 184 } 185 186 // Assignments to outputs. 187 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output) 188 { 189 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType())) 190 { 191 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType()); 192 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT; 193 194 src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << output->name << ");\n"; 195 } 196 else 197 src << "\t" << outputPrefix << output->name << " = " << output->name << ";\n"; 198 } 199 200 src << "}\n"; 201 202 return src.str(); 203} 204 205struct FragmentOutputLayout 206{ 207 std::vector<const Symbol*> locationSymbols; //! Symbols by location 208 std::map<std::string, int> locationMap; //! Map from symbol name to start location 209}; 210 211static void generateFragShaderOutputDecl (std::ostream& src, const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& outputPrefix) 212{ 213 for (int outNdx = 0; outNdx < (int)shaderSpec.outputs.size(); ++outNdx) 214 { 215 const Symbol& output = shaderSpec.outputs[outNdx]; 216 const int location = de::lookup(outLocationMap, output.name); 217 const std::string outVarName = outputPrefix + output.name; 218 glu::VariableDeclaration decl (output.varType, outVarName, glu::STORAGE_OUT, glu::INTERPOLATION_LAST, glu::Layout(location)); 219 220 TCU_CHECK_INTERNAL(output.varType.isBasicType()); 221 222 if (useIntOutputs && glu::isDataTypeFloatOrVec(output.varType.getBasicType())) 223 { 224 const int vecSize = glu::getDataTypeScalarSize(output.varType.getBasicType()); 225 const glu::DataType uintBasicType = vecSize > 1 ? glu::getDataTypeUintVec(vecSize) : glu::TYPE_UINT; 226 const glu::VarType uintType (uintBasicType, glu::PRECISION_HIGHP); 227 228 decl.varType = uintType; 229 src << decl << ";\n"; 230 } 231 else if (glu::isDataTypeBoolOrBVec(output.varType.getBasicType())) 232 { 233 const int vecSize = glu::getDataTypeScalarSize(output.varType.getBasicType()); 234 const glu::DataType intBasicType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT; 235 const glu::VarType intType (intBasicType, glu::PRECISION_HIGHP); 236 237 decl.varType = intType; 238 src << decl << ";\n"; 239 } 240 else if (glu::isDataTypeMatrix(output.varType.getBasicType())) 241 { 242 const int vecSize = glu::getDataTypeMatrixNumRows(output.varType.getBasicType()); 243 const int numVecs = glu::getDataTypeMatrixNumColumns(output.varType.getBasicType()); 244 const glu::DataType uintBasicType = glu::getDataTypeUintVec(vecSize); 245 const glu::VarType uintType (uintBasicType, glu::PRECISION_HIGHP); 246 247 decl.varType = uintType; 248 for (int vecNdx = 0; vecNdx < numVecs; ++vecNdx) 249 { 250 decl.name = outVarName + "_" + de::toString(vecNdx); 251 decl.layout.location = location + vecNdx; 252 src << decl << ";\n"; 253 } 254 } 255 else 256 src << decl << ";\n"; 257 } 258} 259 260static void generateFragShaderOutAssign (std::ostream& src, const ShaderSpec& shaderSpec, bool useIntOutputs, const std::string& valuePrefix, const std::string& outputPrefix) 261{ 262 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output) 263 { 264 if (useIntOutputs && glu::isDataTypeFloatOrVec(output->varType.getBasicType())) 265 src << " o_" << output->name << " = floatBitsToUint(" << valuePrefix << output->name << ");\n"; 266 else if (glu::isDataTypeMatrix(output->varType.getBasicType())) 267 { 268 const int numVecs = glu::getDataTypeMatrixNumColumns(output->varType.getBasicType()); 269 270 for (int vecNdx = 0; vecNdx < numVecs; ++vecNdx) 271 if (useIntOutputs) 272 src << "\t" << outputPrefix << output->name << "_" << vecNdx << " = floatBitsToUint(" << valuePrefix << output->name << "[" << vecNdx << "]);\n"; 273 else 274 src << "\t" << outputPrefix << output->name << "_" << vecNdx << " = " << valuePrefix << output->name << "[" << vecNdx << "];\n"; 275 } 276 else if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType())) 277 { 278 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType()); 279 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT; 280 281 src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << valuePrefix << output->name << ");\n"; 282 } 283 else 284 src << "\t" << outputPrefix << output->name << " = " << valuePrefix << output->name << ";\n"; 285 } 286} 287 288static std::string generatePassthroughFragmentShader (const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& inputPrefix, const std::string& outputPrefix) 289{ 290 std::ostringstream src; 291 292 src << "#version 310 es\n"; 293 294 if (!shaderSpec.globalDeclarations.empty()) 295 src << shaderSpec.globalDeclarations << "\n"; 296 297 int locationNumber = 0; 298 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber) 299 { 300 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType())) 301 { 302 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType()); 303 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT; 304 const glu::VarType intType (intBaseType, glu::PRECISION_HIGHP); 305 306 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(intType, inputPrefix + output->name) << ";\n"; 307 } 308 else 309 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(output->varType, inputPrefix + output->name) << ";\n"; 310 } 311 312 generateFragShaderOutputDecl(src, shaderSpec, useIntOutputs, outLocationMap, outputPrefix); 313 314 src << "\nvoid main (void)\n{\n"; 315 316 generateFragShaderOutAssign(src, shaderSpec, useIntOutputs, inputPrefix, outputPrefix); 317 318 src << "}\n"; 319 320 return src.str(); 321} 322 323static std::string generateGeometryShader (const ShaderSpec& shaderSpec, const std::string& inputPrefix, const std::string& outputPrefix) 324{ 325 DE_ASSERT(!inputPrefix.empty() && !outputPrefix.empty()); 326 327 std::ostringstream src; 328 329 src << "#version 310 es\n" 330 "#extension GL_EXT_geometry_shader : require\n"; 331 332 if (!shaderSpec.globalDeclarations.empty()) 333 src << shaderSpec.globalDeclarations << "\n"; 334 335 src << "layout(points) in;\n" 336 << "layout(points, max_vertices = 1) out;\n"; 337 338 int locationNumber = 0; 339 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber) 340 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(input->varType, inputPrefix + input->name) << "[];\n"; 341 342 locationNumber = 0; 343 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output, ++locationNumber) 344 { 345 DE_ASSERT(output->varType.isBasicType()); 346 347 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType())) 348 { 349 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType()); 350 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT; 351 const glu::VarType intType (intBaseType, glu::PRECISION_HIGHP); 352 353 src << "layout(location = " << locationNumber << ") flat out " << glu::declare(intType, outputPrefix + output->name) << ";\n"; 354 } 355 else 356 src << "layout(location = " << locationNumber << ") flat out " << glu::declare(output->varType, outputPrefix + output->name) << ";\n"; 357 } 358 359 src << "\n" 360 << "void main (void)\n" 361 << "{\n" 362 << " gl_Position = gl_in[0].gl_Position;\n\n"; 363 364 // Fetch input variables 365 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input) 366 src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << "[0];\n"; 367 368 // Declare local output variables. 369 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output) 370 src << "\t" << glu::declare(output->varType, output->name) << ";\n"; 371 372 src << "\n"; 373 374 // Operation - indented to correct level. 375 { 376 std::istringstream opSrc (shaderSpec.source); 377 std::string line; 378 379 while (std::getline(opSrc, line)) 380 src << "\t" << line << "\n"; 381 } 382 383 // Assignments to outputs. 384 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output) 385 { 386 if (glu::isDataTypeBoolOrBVec(output->varType.getBasicType())) 387 { 388 const int vecSize = glu::getDataTypeScalarSize(output->varType.getBasicType()); 389 const glu::DataType intBaseType = vecSize > 1 ? glu::getDataTypeIntVec(vecSize) : glu::TYPE_INT; 390 391 src << "\t" << outputPrefix << output->name << " = " << glu::getDataTypeName(intBaseType) << "(" << output->name << ");\n"; 392 } 393 else 394 src << "\t" << outputPrefix << output->name << " = " << output->name << ";\n"; 395 } 396 397 src << " EmitVertex();\n" 398 << " EndPrimitive();\n" 399 << "}\n"; 400 401 return src.str(); 402} 403 404static std::string generateFragmentShader (const ShaderSpec& shaderSpec, bool useIntOutputs, const std::map<std::string, int>& outLocationMap, const std::string& inputPrefix, const std::string& outputPrefix) 405{ 406 std::ostringstream src; 407 src << "#version 310 es\n"; 408 if (!shaderSpec.globalDeclarations.empty()) 409 src << shaderSpec.globalDeclarations << "\n"; 410 411 int locationNumber = 0; 412 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input, ++locationNumber) 413 src << "layout(location = " << locationNumber << ") flat in " << glu::declare(input->varType, inputPrefix + input->name) << ";\n"; 414 415 generateFragShaderOutputDecl(src, shaderSpec, useIntOutputs, outLocationMap, outputPrefix); 416 417 src << "\nvoid main (void)\n{\n"; 418 419 // Declare & fetch local input variables 420 for (vector<Symbol>::const_iterator input = shaderSpec.inputs.begin(); input != shaderSpec.inputs.end(); ++input) 421 src << "\t" << glu::declare(input->varType, input->name) << " = " << inputPrefix << input->name << ";\n"; 422 423 // Declare output variables 424 for (vector<Symbol>::const_iterator output = shaderSpec.outputs.begin(); output != shaderSpec.outputs.end(); ++output) 425 src << "\t" << glu::declare(output->varType, output->name) << ";\n"; 426 427 // Operation - indented to correct level. 428 { 429 std::istringstream opSrc (shaderSpec.source); 430 std::string line; 431 432 while (std::getline(opSrc, line)) 433 src << "\t" << line << "\n"; 434 } 435 436 generateFragShaderOutAssign(src, shaderSpec, useIntOutputs, "", outputPrefix); 437 438 src << "}\n"; 439 440 return src.str(); 441} 442 443// FragmentOutExecutor 444 445class FragmentOutExecutor : public ShaderExecutor 446{ 447public: 448 FragmentOutExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType); 449 virtual ~FragmentOutExecutor (void); 450 451 virtual void execute (const Context& ctx, 452 int numValues, 453 const void* const* inputs, 454 void* const* outputs); 455 456protected: 457 const FragmentOutputLayout m_outputLayout; 458private: 459 void bindAttributes (const Context& ctx, 460 Allocator& memAlloc, 461 int numValues, 462 const void* const* inputs); 463 464 void addAttribute (const Context& ctx, 465 Allocator& memAlloc, 466 deUint32 bindingLocation, 467 VkFormat format, 468 deUint32 sizePerElement, 469 deUint32 count, 470 const void* dataPtr); 471 // reinit render data members 472 virtual void clearRenderData (void); 473 474 typedef de::SharedPtr<Unique<VkImage> > VkImageSp; 475 typedef de::SharedPtr<Unique<VkImageView> > VkImageViewSp; 476 typedef de::SharedPtr<Unique<VkBuffer> > VkBufferSp; 477 typedef de::SharedPtr<de::UniquePtr<Allocation> > AllocationSp; 478 479 std::vector<VkVertexInputBindingDescription> m_vertexBindingDescriptions; 480 std::vector<VkVertexInputAttributeDescription> m_vertexAttributeDescriptions; 481 std::vector<VkBufferSp> m_vertexBuffers; 482 std::vector<AllocationSp> m_vertexBufferAllocs; 483}; 484 485static FragmentOutputLayout computeFragmentOutputLayout (const std::vector<Symbol>& symbols) 486{ 487 FragmentOutputLayout ret; 488 int location = 0; 489 490 for (std::vector<Symbol>::const_iterator it = symbols.begin(); it != symbols.end(); ++it) 491 { 492 const int numLocations = glu::getDataTypeNumLocations(it->varType.getBasicType()); 493 494 TCU_CHECK_INTERNAL(!de::contains(ret.locationMap, it->name)); 495 de::insert(ret.locationMap, it->name, location); 496 location += numLocations; 497 498 for (int ndx = 0; ndx < numLocations; ++ndx) 499 ret.locationSymbols.push_back(&*it); 500 } 501 502 return ret; 503} 504 505FragmentOutExecutor::FragmentOutExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType) 506 : ShaderExecutor (shaderSpec, shaderType) 507 , m_outputLayout (computeFragmentOutputLayout(m_shaderSpec.outputs)) 508{ 509} 510 511FragmentOutExecutor::~FragmentOutExecutor (void) 512{ 513} 514 515static std::vector<tcu::Vec2> computeVertexPositions (int numValues, const tcu::IVec2& renderSize) 516{ 517 std::vector<tcu::Vec2> positions(numValues); 518 for (int valNdx = 0; valNdx < numValues; valNdx++) 519 { 520 const int ix = valNdx % renderSize.x(); 521 const int iy = valNdx / renderSize.x(); 522 const float fx = -1.0f + 2.0f*((float(ix) + 0.5f) / float(renderSize.x())); 523 const float fy = -1.0f + 2.0f*((float(iy) + 0.5f) / float(renderSize.y())); 524 525 positions[valNdx] = tcu::Vec2(fx, fy); 526 } 527 528 return positions; 529} 530 531static tcu::TextureFormat getRenderbufferFormatForOutput (const glu::VarType& outputType, bool useIntOutputs) 532{ 533 const tcu::TextureFormat::ChannelOrder channelOrderMap[] = 534 { 535 tcu::TextureFormat::R, 536 tcu::TextureFormat::RG, 537 tcu::TextureFormat::RGBA, // No RGB variants available. 538 tcu::TextureFormat::RGBA 539 }; 540 541 const glu::DataType basicType = outputType.getBasicType(); 542 const int numComps = glu::getDataTypeNumComponents(basicType); 543 tcu::TextureFormat::ChannelType channelType; 544 545 switch (glu::getDataTypeScalarType(basicType)) 546 { 547 case glu::TYPE_UINT: channelType = tcu::TextureFormat::UNSIGNED_INT32; break; 548 case glu::TYPE_INT: channelType = tcu::TextureFormat::SIGNED_INT32; break; 549 case glu::TYPE_BOOL: channelType = tcu::TextureFormat::SIGNED_INT32; break; 550 case glu::TYPE_FLOAT: channelType = useIntOutputs ? tcu::TextureFormat::UNSIGNED_INT32 : tcu::TextureFormat::FLOAT; break; 551 default: 552 throw tcu::InternalError("Invalid output type"); 553 } 554 555 DE_ASSERT(de::inRange<int>(numComps, 1, DE_LENGTH_OF_ARRAY(channelOrderMap))); 556 557 return tcu::TextureFormat(channelOrderMap[numComps-1], channelType); 558} 559 560static VkFormat getAttributeFormat (const glu::DataType dataType) 561{ 562 switch (dataType) 563 { 564 case glu::TYPE_FLOAT: return VK_FORMAT_R32_SFLOAT; 565 case glu::TYPE_FLOAT_VEC2: return VK_FORMAT_R32G32_SFLOAT; 566 case glu::TYPE_FLOAT_VEC3: return VK_FORMAT_R32G32B32_SFLOAT; 567 case glu::TYPE_FLOAT_VEC4: return VK_FORMAT_R32G32B32A32_SFLOAT; 568 569 case glu::TYPE_INT: return VK_FORMAT_R32_SINT; 570 case glu::TYPE_INT_VEC2: return VK_FORMAT_R32G32_SINT; 571 case glu::TYPE_INT_VEC3: return VK_FORMAT_R32G32B32_SINT; 572 case glu::TYPE_INT_VEC4: return VK_FORMAT_R32G32B32A32_SINT; 573 574 case glu::TYPE_UINT: return VK_FORMAT_R32_UINT; 575 case glu::TYPE_UINT_VEC2: return VK_FORMAT_R32G32_UINT; 576 case glu::TYPE_UINT_VEC3: return VK_FORMAT_R32G32B32_UINT; 577 case glu::TYPE_UINT_VEC4: return VK_FORMAT_R32G32B32A32_UINT; 578 579 case glu::TYPE_FLOAT_MAT2: return VK_FORMAT_R32G32_SFLOAT; 580 case glu::TYPE_FLOAT_MAT2X3: return VK_FORMAT_R32G32B32_SFLOAT; 581 case glu::TYPE_FLOAT_MAT2X4: return VK_FORMAT_R32G32B32A32_SFLOAT; 582 case glu::TYPE_FLOAT_MAT3X2: return VK_FORMAT_R32G32_SFLOAT; 583 case glu::TYPE_FLOAT_MAT3: return VK_FORMAT_R32G32B32_SFLOAT; 584 case glu::TYPE_FLOAT_MAT3X4: return VK_FORMAT_R32G32B32A32_SFLOAT; 585 case glu::TYPE_FLOAT_MAT4X2: return VK_FORMAT_R32G32_SFLOAT; 586 case glu::TYPE_FLOAT_MAT4X3: return VK_FORMAT_R32G32B32_SFLOAT; 587 case glu::TYPE_FLOAT_MAT4: return VK_FORMAT_R32G32B32A32_SFLOAT; 588 default: 589 DE_ASSERT(false); 590 return VK_FORMAT_UNDEFINED; 591 } 592} 593 594void FragmentOutExecutor::addAttribute (const Context& ctx, Allocator& memAlloc, deUint32 bindingLocation, VkFormat format, deUint32 sizePerElement, deUint32 count, const void* dataPtr) 595{ 596 // Add binding specification 597 const deUint32 binding = (deUint32)m_vertexBindingDescriptions.size(); 598 const VkVertexInputBindingDescription bindingDescription = 599 { 600 binding, 601 sizePerElement, 602 VK_VERTEX_INPUT_RATE_VERTEX 603 }; 604 605 m_vertexBindingDescriptions.push_back(bindingDescription); 606 607 // Add location and format specification 608 const VkVertexInputAttributeDescription attributeDescription = 609 { 610 bindingLocation, // deUint32 location; 611 binding, // deUint32 binding; 612 format, // VkFormat format; 613 0u, // deUint32 offsetInBytes; 614 }; 615 616 m_vertexAttributeDescriptions.push_back(attributeDescription); 617 618 // Upload data to buffer 619 const VkDevice vkDevice = ctx.getDevice(); 620 const DeviceInterface& vk = ctx.getDeviceInterface(); 621 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex(); 622 623 const VkDeviceSize inputSize = sizePerElement * count; 624 const VkBufferCreateInfo vertexBufferParams = 625 { 626 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 627 DE_NULL, // const void* pNext; 628 0u, // VkBufferCreateFlags flags; 629 inputSize, // VkDeviceSize size; 630 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; 631 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 632 1u, // deUint32 queueFamilyCount; 633 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 634 }; 635 636 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &vertexBufferParams); 637 de::MovePtr<Allocation> alloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible); 638 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset())); 639 640 deMemcpy(alloc->getHostPtr(), dataPtr, (size_t)inputSize); 641 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), inputSize); 642 643 m_vertexBuffers.push_back(de::SharedPtr<Unique<VkBuffer> >(new Unique<VkBuffer>(buffer))); 644 m_vertexBufferAllocs.push_back(de::SharedPtr<de::UniquePtr<Allocation> >(new de::UniquePtr<Allocation>(alloc))); 645} 646 647void FragmentOutExecutor::bindAttributes (const Context& ctx, Allocator& memAlloc, int numValues, const void* const* inputs) 648{ 649 // Input attributes 650 for (int inputNdx = 0; inputNdx < (int)m_shaderSpec.inputs.size(); inputNdx++) 651 { 652 const Symbol& symbol = m_shaderSpec.inputs[inputNdx]; 653 const void* ptr = inputs[inputNdx]; 654 const glu::DataType basicType = symbol.varType.getBasicType(); 655 const int vecSize = glu::getDataTypeScalarSize(basicType); 656 const VkFormat format = getAttributeFormat(basicType); 657 int elementSize = 0; 658 int numAttrsToAdd = 1; 659 660 if (glu::isDataTypeFloatOrVec(basicType)) 661 elementSize = sizeof(float); 662 else if (glu::isDataTypeIntOrIVec(basicType)) 663 elementSize = sizeof(int); 664 else if (glu::isDataTypeUintOrUVec(basicType)) 665 elementSize = sizeof(deUint32); 666 else if (glu::isDataTypeMatrix(basicType)) 667 { 668 int numRows = glu::getDataTypeMatrixNumRows(basicType); 669 int numCols = glu::getDataTypeMatrixNumColumns(basicType); 670 671 elementSize = numRows * numCols * (int)sizeof(float); 672 numAttrsToAdd = numCols; 673 } 674 else 675 DE_ASSERT(false); 676 677 // add attributes, in case of matrix every column is binded as an attribute 678 for (int attrNdx = 0; attrNdx < numAttrsToAdd; attrNdx++) 679 { 680 addAttribute(ctx, memAlloc, (deUint32)m_vertexBindingDescriptions.size(), format, elementSize * vecSize, numValues, ptr); 681 } 682 } 683} 684 685void FragmentOutExecutor::clearRenderData (void) 686{ 687 m_vertexBindingDescriptions.clear(); 688 m_vertexAttributeDescriptions.clear(); 689 m_vertexBuffers.clear(); 690 m_vertexBufferAllocs.clear(); 691} 692 693void FragmentOutExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs) 694{ 695 checkSupported(ctx, m_shaderType); 696 697 const VkDevice vkDevice = ctx.getDevice(); 698 const DeviceInterface& vk = ctx.getDeviceInterface(); 699 const VkQueue queue = ctx.getUniversalQueue(); 700 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex(); 701 Allocator& memAlloc = ctx.getDefaultAllocator(); 702 703 const deUint32 renderSizeX = de::min(static_cast<deUint32>(DEFAULT_RENDER_WIDTH), (deUint32)numValues); 704 const deUint32 renderSizeY = ((deUint32)numValues / renderSizeX) + (((deUint32)numValues % renderSizeX != 0) ? 1u : 0u); 705 const tcu::UVec2 renderSize (renderSizeX, renderSizeY); 706 std::vector<tcu::Vec2> positions; 707 708 const bool useGeometryShader = m_shaderType == glu::SHADERTYPE_GEOMETRY; 709 710 std::vector<VkImageSp> colorImages; 711 std::vector<VkImageMemoryBarrier> colorImagePreRenderBarriers; 712 std::vector<VkImageMemoryBarrier> colorImagePostRenderBarriers; 713 std::vector<AllocationSp> colorImageAllocs; 714 std::vector<VkAttachmentDescription> attachments; 715 std::vector<VkClearValue> attachmentClearValues; 716 std::vector<VkImageViewSp> colorImageViews; 717 718 std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentStates; 719 std::vector<VkAttachmentReference> colorAttachmentReferences; 720 721 Move<VkRenderPass> renderPass; 722 Move<VkFramebuffer> framebuffer; 723 Move<VkPipelineLayout> pipelineLayout; 724 Move<VkPipeline> graphicsPipeline; 725 726 Move<VkShaderModule> vertexShaderModule; 727 Move<VkShaderModule> geometryShaderModule; 728 Move<VkShaderModule> fragmentShaderModule; 729 730 Move<VkCommandPool> cmdPool; 731 Move<VkCommandBuffer> cmdBuffer; 732 733 Move<VkFence> fence; 734 735 Move<VkDescriptorPool> descriptorPool; 736 Move<VkDescriptorSetLayout> descriptorSetLayout; 737 Move<VkDescriptorSet> descriptorSet; 738 739 clearRenderData(); 740 741 // Compute positions - 1px points are used to drive fragment shading. 742 positions = computeVertexPositions(numValues, renderSize.cast<int>()); 743 744 // Bind attributes 745 addAttribute(ctx, memAlloc, 0u, VK_FORMAT_R32G32_SFLOAT, sizeof(tcu::Vec2), (deUint32)positions.size(), &positions[0]); 746 bindAttributes(ctx, memAlloc, numValues, inputs); 747 748 // Create color images 749 { 750 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = 751 { 752 VK_FALSE, // VkBool32 blendEnable; 753 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; 754 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; 755 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor; 756 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 757 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destAlphaBlendFactor; 758 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha; 759 (VK_COLOR_COMPONENT_R_BIT | 760 VK_COLOR_COMPONENT_G_BIT | 761 VK_COLOR_COMPONENT_B_BIT | 762 VK_COLOR_COMPONENT_A_BIT) // VkColorComponentFlags colorWriteMask; 763 }; 764 765 for (int outNdx = 0; outNdx < (int)m_outputLayout.locationSymbols.size(); ++outNdx) 766 { 767 const bool isFloat = isDataTypeFloatOrVec(m_shaderSpec.outputs[outNdx].varType.getBasicType()); 768 const bool isSigned = isDataTypeIntOrIVec (m_shaderSpec.outputs[outNdx].varType.getBasicType()); 769 const bool isBool = isDataTypeBoolOrBVec(m_shaderSpec.outputs[outNdx].varType.getBasicType()); 770 const VkFormat colorFormat = isFloat ? VK_FORMAT_R32G32B32A32_SFLOAT : (isSigned || isBool ? VK_FORMAT_R32G32B32A32_SINT : VK_FORMAT_R32G32B32A32_UINT); 771 772 const VkImageCreateInfo colorImageParams = 773 { 774 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 775 DE_NULL, // const void* pNext; 776 0u, // VkImageCreateFlags flags; 777 VK_IMAGE_TYPE_2D, // VkImageType imageType; 778 colorFormat, // VkFormat format; 779 { renderSize.x(), renderSize.y(), 1u }, // VkExtent3D extent; 780 1u, // deUint32 mipLevels; 781 1u, // deUint32 arraySize; 782 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 783 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 784 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; 785 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 786 1u, // deUint32 queueFamilyCount; 787 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 788 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 789 }; 790 791 const VkAttachmentDescription colorAttachmentDescription = 792 { 793 0u, // VkAttachmentDescriptorFlags flags; 794 colorFormat, // VkFormat format; 795 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 796 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 797 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 798 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 799 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 800 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 801 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 802 }; 803 804 Move<VkImage> colorImage = createImage(vk, vkDevice, &colorImageParams); 805 colorImages.push_back(de::SharedPtr<Unique<VkImage> >(new Unique<VkImage>(colorImage))); 806 attachmentClearValues.push_back(getDefaultClearColor()); 807 808 // Allocate and bind color image memory 809 { 810 de::MovePtr<Allocation> colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *((const VkImage*) colorImages.back().get())), MemoryRequirement::Any); 811 VK_CHECK(vk.bindImageMemory(vkDevice, colorImages.back().get()->get(), colorImageAlloc->getMemory(), colorImageAlloc->getOffset())); 812 colorImageAllocs.push_back(de::SharedPtr<de::UniquePtr<Allocation> >(new de::UniquePtr<Allocation>(colorImageAlloc))); 813 814 attachments.push_back(colorAttachmentDescription); 815 colorBlendAttachmentStates.push_back(colorBlendAttachmentState); 816 817 const VkAttachmentReference colorAttachmentReference = { 818 (deUint32) (colorImages.size() - 1), // deUint32 attachment; 819 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 820 }; 821 822 colorAttachmentReferences.push_back(colorAttachmentReference); 823 } 824 825 // Create color attachment view 826 { 827 const VkImageViewCreateInfo colorImageViewParams = 828 { 829 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 830 DE_NULL, // const void* pNext; 831 0u, // VkImageViewCreateFlags flags; 832 colorImages.back().get()->get(), // VkImage image; 833 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 834 colorFormat, // VkFormat format; 835 { 836 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r; 837 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g; 838 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b; 839 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a; 840 }, // VkComponentMapping components; 841 { 842 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 843 0u, // deUint32 baseMipLevel; 844 1u, // deUint32 mipLevels; 845 0u, // deUint32 baseArraySlice; 846 1u // deUint32 arraySize; 847 } // VkImageSubresourceRange subresourceRange; 848 }; 849 850 Move<VkImageView> colorImageView = createImageView(vk, vkDevice, &colorImageViewParams); 851 colorImageViews.push_back(de::SharedPtr<Unique<VkImageView> >(new Unique<VkImageView>(colorImageView))); 852 853 const VkImageMemoryBarrier colorImagePreRenderBarrier = 854 { 855 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType 856 DE_NULL, // pNext 857 0u, // srcAccessMask 858 (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 859 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), // dstAccessMask 860 VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout 861 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout 862 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex 863 VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex 864 colorImages.back().get()->get(), // image 865 { 866 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask 867 0u, // baseMipLevel 868 1u, // levelCount 869 0u, // baseArrayLayer 870 1u, // layerCount 871 } // subresourceRange 872 }; 873 colorImagePreRenderBarriers.push_back(colorImagePreRenderBarrier); 874 875 const VkImageMemoryBarrier colorImagePostRenderBarrier = 876 { 877 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType 878 DE_NULL, // pNext 879 (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 880 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), // srcAccessMask 881 VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask 882 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout 883 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout 884 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex 885 VK_QUEUE_FAMILY_IGNORED, // dstQueueFamilyIndex 886 colorImages.back().get()->get(), // image 887 { 888 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask 889 0u, // baseMipLevel 890 1u, // levelCount 891 0u, // baseArrayLayer 892 1u, // layerCount 893 } // subresourceRange 894 }; 895 colorImagePostRenderBarriers.push_back(colorImagePostRenderBarrier); 896 } 897 } 898 } 899 900 // Create render pass 901 { 902 const VkSubpassDescription subpassDescription = 903 { 904 0u, // VkSubpassDescriptionFlags flags; 905 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 906 0u, // deUint32 inputCount; 907 DE_NULL, // const VkAttachmentReference* pInputAttachments; 908 (deUint32)colorImages.size(), // deUint32 colorCount; 909 &colorAttachmentReferences[0], // const VkAttachmentReference* colorAttachments; 910 DE_NULL, // const VkAttachmentReference* resolveAttachments; 911 DE_NULL, // VkAttachmentReference depthStencilAttachment; 912 0u, // deUint32 preserveCount; 913 DE_NULL // const VkAttachmentReference* pPreserveAttachments; 914 }; 915 916 const VkRenderPassCreateInfo renderPassParams = 917 { 918 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 919 DE_NULL, // const void* pNext; 920 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags; 921 (deUint32)attachments.size(), // deUint32 attachmentCount; 922 &attachments[0], // const VkAttachmentDescription* pAttachments; 923 1u, // deUint32 subpassCount; 924 &subpassDescription, // const VkSubpassDescription* pSubpasses; 925 0u, // deUint32 dependencyCount; 926 DE_NULL // const VkSubpassDependency* pDependencies; 927 }; 928 929 renderPass = createRenderPass(vk, vkDevice, &renderPassParams); 930 } 931 932 // Create framebuffer 933 { 934 std::vector<VkImageView> views(colorImageViews.size()); 935 for (size_t i = 0; i < colorImageViews.size(); i++) 936 { 937 views[i] = colorImageViews[i].get()->get(); 938 } 939 940 const VkFramebufferCreateInfo framebufferParams = 941 { 942 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 943 DE_NULL, // const void* pNext; 944 0u, // VkFramebufferCreateFlags flags; 945 *renderPass, // VkRenderPass renderPass; 946 (deUint32)views.size(), // deUint32 attachmentCount; 947 &views[0], // const VkImageView* pAttachments; 948 (deUint32)renderSize.x(), // deUint32 width; 949 (deUint32)renderSize.y(), // deUint32 height; 950 1u // deUint32 layers; 951 }; 952 953 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams); 954 } 955 956 // Create descriptors 957 { 958 addUniforms(vkDevice, vk, queue, queueFamilyIndex, memAlloc); 959 960 descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice); 961 if (!m_uniformInfos.empty()) 962 descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 963 else 964 { 965 const VkDescriptorPoolSize poolSizeCount = { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1 }; 966 const VkDescriptorPoolCreateInfo createInfo = 967 { 968 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, 969 DE_NULL, 970 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 971 1u, 972 1u, 973 &poolSizeCount, 974 }; 975 976 descriptorPool = createDescriptorPool(vk, vkDevice, &createInfo); 977 } 978 979 const VkDescriptorSetAllocateInfo allocInfo = 980 { 981 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 982 DE_NULL, 983 *descriptorPool, 984 1u, 985 &*descriptorSetLayout 986 }; 987 988 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo); 989 990 // Update descriptors 991 { 992 vk::DescriptorSetUpdateBuilder descriptorSetUpdateBuilder; 993 994 uploadUniforms(descriptorSetUpdateBuilder, *descriptorSet); 995 996 descriptorSetUpdateBuilder.update(vk, vkDevice); 997 } 998 } 999 1000 // Create pipeline layout 1001 { 1002 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 1003 { 1004 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 1005 DE_NULL, // const void* pNext; 1006 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags; 1007 1, // deUint32 descriptorSetCount; 1008 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts; 1009 0u, // deUint32 pushConstantRangeCount; 1010 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 1011 }; 1012 1013 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); 1014 } 1015 1016 // Create shaders 1017 { 1018 vertexShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("vert"), 0); 1019 fragmentShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("frag"), 0); 1020 1021 if (useGeometryShader) 1022 { 1023 geometryShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("geom"), 0); 1024 } 1025 } 1026 1027 // Create pipeline 1028 { 1029 std::vector<VkPipelineShaderStageCreateInfo> shaderStageParams; 1030 1031 const VkPipelineShaderStageCreateInfo vertexShaderStageParams = 1032 { 1033 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 1034 DE_NULL, // const void* pNext; 1035 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 1036 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; 1037 *vertexShaderModule, // VkShaderModule module; 1038 "main", // const char* pName; 1039 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 1040 }; 1041 1042 const VkPipelineShaderStageCreateInfo fragmentShaderStageParams = 1043 { 1044 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 1045 DE_NULL, // const void* pNext; 1046 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 1047 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage; 1048 *fragmentShaderModule, // VkShaderModule module; 1049 "main", // const char* pName; 1050 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 1051 }; 1052 1053 shaderStageParams.push_back(vertexShaderStageParams); 1054 shaderStageParams.push_back(fragmentShaderStageParams); 1055 1056 if (useGeometryShader) 1057 { 1058 const VkPipelineShaderStageCreateInfo geometryShaderStageParams = 1059 { 1060 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 1061 DE_NULL, // const void* pNext; 1062 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 1063 VK_SHADER_STAGE_GEOMETRY_BIT, // VkShaderStageFlagBits stage; 1064 *geometryShaderModule, // VkShaderModule module; 1065 "main", // VkShader shader; 1066 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 1067 }; 1068 1069 shaderStageParams.push_back(geometryShaderStageParams); 1070 } 1071 1072 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 1073 { 1074 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 1075 DE_NULL, // const void* pNext; 1076 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags; 1077 (deUint32)m_vertexBindingDescriptions.size(), // deUint32 bindingCount; 1078 &m_vertexBindingDescriptions[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 1079 (deUint32)m_vertexAttributeDescriptions.size(), // deUint32 attributeCount; 1080 &m_vertexAttributeDescriptions[0], // const VkVertexInputAttributeDescription* pvertexAttributeDescriptions; 1081 }; 1082 1083 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = 1084 { 1085 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 1086 DE_NULL, // const void* pNext; 1087 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags; 1088 VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // VkPrimitiveTopology topology; 1089 DE_FALSE // VkBool32 primitiveRestartEnable; 1090 }; 1091 1092 const VkViewport viewport = 1093 { 1094 0.0f, // float originX; 1095 0.0f, // float originY; 1096 (float)renderSize.x(), // float width; 1097 (float)renderSize.y(), // float height; 1098 0.0f, // float minDepth; 1099 1.0f // float maxDepth; 1100 }; 1101 1102 const VkRect2D scissor = 1103 { 1104 { 1105 0u, // deUint32 x; 1106 0u, // deUint32 y; 1107 }, // VkOffset2D offset; 1108 { 1109 renderSize.x(), // deUint32 width; 1110 renderSize.y(), // deUint32 height; 1111 }, // VkExtent2D extent; 1112 }; 1113 1114 const VkPipelineViewportStateCreateInfo viewportStateParams = 1115 { 1116 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 1117 DE_NULL, // const void* pNext; 1118 0u, // VkPipelineViewportStateCreateFlags flags; 1119 1u, // deUint32 viewportCount; 1120 &viewport, // const VkViewport* pViewports; 1121 1u, // deUint32 scissorsCount; 1122 &scissor // const VkRect2D* pScissors; 1123 }; 1124 1125 const VkPipelineRasterizationStateCreateInfo rasterStateParams = 1126 { 1127 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 1128 DE_NULL, // const void* pNext; 1129 (VkPipelineRasterizationStateCreateFlags)0u, //VkPipelineRasterizationStateCreateFlags flags; 1130 VK_FALSE, // VkBool32 depthClipEnable; 1131 VK_FALSE, // VkBool32 rasterizerDiscardEnable; 1132 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 1133 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 1134 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 1135 VK_FALSE, // VkBool32 depthBiasEnable; 1136 0.0f, // float depthBias; 1137 0.0f, // float depthBiasClamp; 1138 0.0f, // float slopeScaledDepthBias; 1139 1.0f // float lineWidth; 1140 }; 1141 1142 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 1143 { 1144 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 1145 DE_NULL, // const void* pNext; 1146 0u, // VkPipelineMultisampleStateCreateFlags flags; 1147 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 1148 VK_FALSE, // VkBool32 sampleShadingEnable; 1149 0.0f, // float minSampleShading; 1150 DE_NULL, // const VkSampleMask* pSampleMask; 1151 VK_FALSE, // VkBool32 alphaToCoverageEnable; 1152 VK_FALSE // VkBool32 alphaToOneEnable; 1153 }; 1154 1155 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 1156 { 1157 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 1158 DE_NULL, // const void* pNext; 1159 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags; 1160 VK_FALSE, // VkBool32 logicOpEnable; 1161 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 1162 (deUint32)colorBlendAttachmentStates.size(), // deUint32 attachmentCount; 1163 &colorBlendAttachmentStates[0], // const VkPipelineColorBlendAttachmentState* pAttachments; 1164 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConst[4]; 1165 }; 1166 1167 const VkGraphicsPipelineCreateInfo graphicsPipelineParams = 1168 { 1169 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 1170 DE_NULL, // const void* pNext; 1171 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags; 1172 (deUint32)shaderStageParams.size(), // deUint32 stageCount; 1173 &shaderStageParams[0], // const VkPipelineShaderStageCreateInfo* pStages; 1174 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 1175 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 1176 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 1177 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; 1178 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState; 1179 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 1180 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 1181 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 1182 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 1183 *pipelineLayout, // VkPipelineLayout layout; 1184 *renderPass, // VkRenderPass renderPass; 1185 0u, // deUint32 subpass; 1186 0u, // VkPipeline basePipelineHandle; 1187 0u // deInt32 basePipelineIndex; 1188 }; 1189 1190 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams); 1191 } 1192 1193 // Create command pool 1194 { 1195 const VkCommandPoolCreateInfo cmdPoolParams = 1196 { 1197 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 1198 DE_NULL, // const void* pNext; 1199 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags; 1200 queueFamilyIndex, // deUint32 queueFamilyIndex; 1201 }; 1202 1203 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams); 1204 } 1205 1206 // Create command buffer 1207 { 1208 const VkCommandBufferAllocateInfo cmdBufferParams = 1209 { 1210 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 1211 DE_NULL, // const void* pNext; 1212 *cmdPool, // VkCmdPool cmdPool; 1213 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level; 1214 1 // deUint32 bufferCount; 1215 }; 1216 1217 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1218 { 1219 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1220 DE_NULL, // const void* pNext; 1221 0u, // VkCmdBufferOptimizeFlags flags; 1222 (const VkCommandBufferInheritanceInfo*)DE_NULL, 1223 }; 1224 1225 const VkRenderPassBeginInfo renderPassBeginInfo = 1226 { 1227 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 1228 DE_NULL, // const void* pNext; 1229 *renderPass, // VkRenderPass renderPass; 1230 *framebuffer, // VkFramebuffer framebuffer; 1231 { { 0, 0 }, { renderSize.x(), renderSize.y() } }, // VkRect2D renderArea; 1232 (deUint32)attachmentClearValues.size(), // deUint32 attachmentCount; 1233 &attachmentClearValues[0] // const VkClearValue* pAttachmentClearValues; 1234 }; 1235 1236 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams); 1237 1238 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); 1239 1240 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 1241 0, (const VkMemoryBarrier*)DE_NULL, 1242 0, (const VkBufferMemoryBarrier*)DE_NULL, 1243 (deUint32)colorImagePreRenderBarriers.size(), colorImagePreRenderBarriers.empty() ? DE_NULL : &colorImagePreRenderBarriers[0]); 1244 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 1245 1246 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline); 1247 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL); 1248 1249 const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size(); 1250 1251 std::vector<VkDeviceSize> offsets(numberOfVertexAttributes, 0); 1252 1253 std::vector<VkBuffer> buffers(numberOfVertexAttributes); 1254 for (size_t i = 0; i < numberOfVertexAttributes; i++) 1255 { 1256 buffers[i] = m_vertexBuffers[i].get()->get(); 1257 } 1258 1259 vk.cmdBindVertexBuffers(*cmdBuffer, 0, numberOfVertexAttributes, &buffers[0], &offsets[0]); 1260 vk.cmdDraw(*cmdBuffer, (deUint32)positions.size(), 1u, 0u, 0u); 1261 1262 vk.cmdEndRenderPass(*cmdBuffer); 1263 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 1264 0, (const VkMemoryBarrier*)DE_NULL, 1265 0, (const VkBufferMemoryBarrier*)DE_NULL, 1266 (deUint32)colorImagePostRenderBarriers.size(), colorImagePostRenderBarriers.empty() ? DE_NULL : &colorImagePostRenderBarriers[0]); 1267 1268 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 1269 } 1270 1271 // Create fence 1272 { 1273 const VkFenceCreateInfo fenceParams = 1274 { 1275 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 1276 DE_NULL, // const void* pNext; 1277 0u // VkFenceCreateFlags flags; 1278 }; 1279 1280 fence = createFence(vk, vkDevice, &fenceParams); 1281 } 1282 1283 // Execute Draw 1284 { 1285 1286 const VkSubmitInfo submitInfo = 1287 { 1288 VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType 1289 DE_NULL, // pNext 1290 0u, // waitSemaphoreCount 1291 DE_NULL, // pWaitSemaphores 1292 (const VkPipelineStageFlags*)DE_NULL, 1293 1u, // commandBufferCount 1294 &cmdBuffer.get(), // pCommandBuffers 1295 0u, // signalSemaphoreCount 1296 DE_NULL // pSignalSemaphores 1297 }; 1298 1299 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get())); 1300 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 1301 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), DE_TRUE, ~(0ull) /* infinity*/)); 1302 } 1303 1304 // Read back result and output 1305 { 1306 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(4 * sizeof(deUint32) * renderSize.x() * renderSize.y()); 1307 const VkBufferCreateInfo readImageBufferParams = 1308 { 1309 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1310 DE_NULL, // const void* pNext; 1311 0u, // VkBufferCreateFlags flags; 1312 imageSizeBytes, // VkDeviceSize size; 1313 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 1314 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1315 1u, // deUint32 queueFamilyCount; 1316 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1317 }; 1318 1319 // constants for image copy 1320 1321 const VkCommandPoolCreateInfo cmdPoolParams = 1322 { 1323 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 1324 DE_NULL, // const void* pNext; 1325 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags; 1326 queueFamilyIndex // deUint32 queueFamilyIndex; 1327 }; 1328 1329 Move<VkCommandPool> copyCmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams); 1330 1331 const VkCommandBufferAllocateInfo cmdBufferParams = 1332 { 1333 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 1334 DE_NULL, // const void* pNext; 1335 *copyCmdPool, // VkCmdPool cmdPool; 1336 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level; 1337 1u // deUint32 bufferCount; 1338 }; 1339 1340 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1341 { 1342 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1343 DE_NULL, // const void* pNext; 1344 0u, // VkCmdBufferOptimizeFlags flags; 1345 (const VkCommandBufferInheritanceInfo*)DE_NULL, 1346 }; 1347 1348 const VkBufferImageCopy copyParams = 1349 { 1350 0u, // VkDeviceSize bufferOffset; 1351 (deUint32)renderSize.x(), // deUint32 bufferRowLength; 1352 (deUint32)renderSize.y(), // deUint32 bufferImageHeight; 1353 { 1354 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect; 1355 0u, // deUint32 mipLevel; 1356 0u, // deUint32 arraySlice; 1357 1u, // deUint32 arraySize; 1358 }, // VkImageSubresource imageSubresource; 1359 { 0u, 0u, 0u }, // VkOffset3D imageOffset; 1360 { renderSize.x(), renderSize.y(), 1u } // VkExtent3D imageExtent; 1361 }; 1362 1363 // Read back pixels. 1364 for (int outNdx = 0; outNdx < (int)m_shaderSpec.outputs.size(); ++outNdx) 1365 { 1366 const Symbol& output = m_shaderSpec.outputs[outNdx]; 1367 const int outSize = output.varType.getScalarSize(); 1368 const int outVecSize = glu::getDataTypeNumComponents(output.varType.getBasicType()); 1369 const int outNumLocs = glu::getDataTypeNumLocations(output.varType.getBasicType()); 1370 deUint32* dstPtrBase = static_cast<deUint32*>(outputs[outNdx]); 1371 const int outLocation = de::lookup(m_outputLayout.locationMap, output.name); 1372 1373 for (int locNdx = 0; locNdx < outNumLocs; ++locNdx) 1374 { 1375 tcu::TextureLevel tmpBuf; 1376 const tcu::TextureFormat format = getRenderbufferFormatForOutput(output.varType, false); 1377 const tcu::TextureFormat readFormat (tcu::TextureFormat::RGBA, format.type); 1378 const Unique<VkBuffer> readImageBuffer(createBuffer(vk, vkDevice, &readImageBufferParams)); 1379 const de::UniquePtr<Allocation> readImageBufferMemory(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible)); 1380 1381 VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset())); 1382 1383 // Copy image to buffer 1384 { 1385 1386 Move<VkCommandBuffer> copyCmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams); 1387 1388 const VkSubmitInfo submitInfo = 1389 { 1390 VK_STRUCTURE_TYPE_SUBMIT_INFO, 1391 DE_NULL, 1392 0u, 1393 (const VkSemaphore*)DE_NULL, 1394 (const VkPipelineStageFlags*)DE_NULL, 1395 1u, 1396 ©CmdBuffer.get(), 1397 0u, 1398 (const VkSemaphore*)DE_NULL, 1399 }; 1400 1401 VK_CHECK(vk.beginCommandBuffer(*copyCmdBuffer, &cmdBufferBeginInfo)); 1402 vk.cmdCopyImageToBuffer(*copyCmdBuffer, colorImages[outLocation + locNdx].get()->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params); 1403 VK_CHECK(vk.endCommandBuffer(*copyCmdBuffer)); 1404 1405 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get())); 1406 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 1407 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */)); 1408 } 1409 1410 const VkMappedMemoryRange range = 1411 { 1412 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType; 1413 DE_NULL, // const void* pNext; 1414 readImageBufferMemory->getMemory(), // VkDeviceMemory mem; 1415 0, // VkDeviceSize offset; 1416 imageSizeBytes, // VkDeviceSize size; 1417 }; 1418 1419 VK_CHECK(vk.invalidateMappedMemoryRanges(vkDevice, 1u, &range)); 1420 1421 tmpBuf.setStorage(readFormat, renderSize.x(), renderSize.y()); 1422 1423 const tcu::TextureFormat resultFormat(tcu::TextureFormat::RGBA, format.type); 1424 const tcu::ConstPixelBufferAccess resultAccess(resultFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr()); 1425 1426 tcu::copy(tmpBuf.getAccess(), resultAccess); 1427 1428 if (outSize == 4 && outNumLocs == 1) 1429 deMemcpy(dstPtrBase, tmpBuf.getAccess().getDataPtr(), numValues * outVecSize * sizeof(deUint32)); 1430 else 1431 { 1432 for (int valNdx = 0; valNdx < numValues; valNdx++) 1433 { 1434 const deUint32* srcPtr = (const deUint32*)tmpBuf.getAccess().getDataPtr() + valNdx * 4; 1435 deUint32* dstPtr = &dstPtrBase[outSize * valNdx + outVecSize * locNdx]; 1436 deMemcpy(dstPtr, srcPtr, outVecSize * sizeof(deUint32)); 1437 } 1438 } 1439 } 1440 } 1441 } 1442} 1443 1444// VertexShaderExecutor 1445 1446class VertexShaderExecutor : public FragmentOutExecutor 1447{ 1448public: 1449 VertexShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType); 1450 virtual ~VertexShaderExecutor (void); 1451 1452 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst;} 1453 1454 virtual void setShaderSources (SourceCollections& programCollection) const; 1455 1456}; 1457 1458VertexShaderExecutor::VertexShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType) 1459 : FragmentOutExecutor (shaderSpec, shaderType) 1460{ 1461} 1462 1463VertexShaderExecutor::~VertexShaderExecutor (void) 1464{ 1465} 1466 1467void VertexShaderExecutor::setShaderSources (SourceCollections& programCollection) const 1468{ 1469 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShader(m_shaderSpec, "a_", "vtx_out_")); 1470 /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */ 1471 programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(m_shaderSpec, false, m_outputLayout.locationMap, "vtx_out_", "o_")); 1472} 1473 1474// GeometryShaderExecutor 1475 1476class GeometryShaderExecutor : public FragmentOutExecutor 1477{ 1478public: 1479 GeometryShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType); 1480 virtual ~GeometryShaderExecutor (void); 1481 1482 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst; } 1483 1484 virtual void setShaderSources (SourceCollections& programCollection) const; 1485 1486}; 1487 1488GeometryShaderExecutor::GeometryShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType) 1489 : FragmentOutExecutor (shaderSpec, shaderType) 1490{ 1491} 1492 1493GeometryShaderExecutor::~GeometryShaderExecutor (void) 1494{ 1495} 1496 1497void GeometryShaderExecutor::setShaderSources (SourceCollections& programCollection) const 1498{ 1499 programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(m_shaderSpec.inputs, "a_", "vtx_out_")); 1500 1501 programCollection.glslSources.add("geom") << glu::GeometrySource(generateGeometryShader(m_shaderSpec, "vtx_out_", "geom_out_")); 1502 1503 /* \todo [2015-09-18 rsipka] set useIntOutputs parameter if needed. */ 1504 programCollection.glslSources.add("frag") << glu::FragmentSource(generatePassthroughFragmentShader(m_shaderSpec, false, m_outputLayout.locationMap, "geom_out_", "o_")); 1505 1506} 1507 1508// FragmentShaderExecutor 1509 1510class FragmentShaderExecutor : public FragmentOutExecutor 1511{ 1512public: 1513 FragmentShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType); 1514 virtual ~FragmentShaderExecutor (void); 1515 1516 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst; } 1517 1518 virtual void setShaderSources (SourceCollections& programCollection) const; 1519 1520}; 1521 1522FragmentShaderExecutor::FragmentShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType) 1523 : FragmentOutExecutor (shaderSpec, shaderType) 1524{ 1525} 1526 1527FragmentShaderExecutor::~FragmentShaderExecutor (void) 1528{ 1529} 1530 1531void FragmentShaderExecutor::setShaderSources (SourceCollections& programCollection) const 1532{ 1533 programCollection.glslSources.add("vert") << glu::VertexSource(generatePassthroughVertexShader(m_shaderSpec.inputs, "a_", "vtx_out_")); 1534 /* \todo [2015-09-11 hegedusd] set useIntOutputs parameter if needed. */ 1535 programCollection.glslSources.add("frag") << glu::FragmentSource(generateFragmentShader(m_shaderSpec, false, m_outputLayout.locationMap, "vtx_out_", "o_")); 1536} 1537 1538// Shared utilities for compute and tess executors 1539 1540static deUint32 getVecStd430ByteAlignment (glu::DataType type) 1541{ 1542 switch (glu::getDataTypeScalarSize(type)) 1543 { 1544 case 1: return 4u; 1545 case 2: return 8u; 1546 case 3: return 16u; 1547 case 4: return 16u; 1548 default: 1549 DE_ASSERT(false); 1550 return 0u; 1551 } 1552} 1553 1554class BufferIoExecutor : public ShaderExecutor 1555{ 1556public: 1557 BufferIoExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType); 1558 virtual ~BufferIoExecutor (void); 1559 1560 virtual void log (tcu::TestLog& dst) const { /* TODO */ (void)dst; } 1561 1562protected: 1563 enum 1564 { 1565 INPUT_BUFFER_BINDING = 0, 1566 OUTPUT_BUFFER_BINDING = 1, 1567 }; 1568 1569 void initBuffers (const Context& ctx, int numValues); 1570 VkBuffer getInputBuffer (void) const { return *m_inputBuffer; } 1571 VkBuffer getOutputBuffer (void) const { return *m_outputBuffer; } 1572 deUint32 getInputStride (void) const { return getLayoutStride(m_inputLayout); } 1573 deUint32 getOutputStride (void) const { return getLayoutStride(m_outputLayout); } 1574 1575 void uploadInputBuffer (const Context& ctx, const void* const* inputPtrs, int numValues); 1576 void readOutputBuffer (const Context& ctx, void* const* outputPtrs, int numValues); 1577 1578 static void declareBufferBlocks (std::ostream& src, const ShaderSpec& spec); 1579 static void generateExecBufferIo(std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName); 1580 1581protected: 1582 Move<VkBuffer> m_inputBuffer; 1583 Move<VkBuffer> m_outputBuffer; 1584 1585private: 1586 struct VarLayout 1587 { 1588 deUint32 offset; 1589 deUint32 stride; 1590 deUint32 matrixStride; 1591 1592 VarLayout (void) : offset(0), stride(0), matrixStride(0) {} 1593 }; 1594 1595 static void computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout); 1596 static deUint32 getLayoutStride (const vector<VarLayout>& layout); 1597 1598 static void copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr); 1599 static void copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr); 1600 1601 de::MovePtr<Allocation> m_inputAlloc; 1602 de::MovePtr<Allocation> m_outputAlloc; 1603 1604 vector<VarLayout> m_inputLayout; 1605 vector<VarLayout> m_outputLayout; 1606}; 1607 1608BufferIoExecutor::BufferIoExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType) 1609 : ShaderExecutor (shaderSpec, shaderType) 1610{ 1611 computeVarLayout(m_shaderSpec.inputs, &m_inputLayout); 1612 computeVarLayout(m_shaderSpec.outputs, &m_outputLayout); 1613} 1614 1615BufferIoExecutor::~BufferIoExecutor (void) 1616{ 1617} 1618 1619inline deUint32 BufferIoExecutor::getLayoutStride (const vector<VarLayout>& layout) 1620{ 1621 return layout.empty() ? 0 : layout[0].stride; 1622} 1623 1624void BufferIoExecutor::computeVarLayout (const std::vector<Symbol>& symbols, std::vector<VarLayout>* layout) 1625{ 1626 deUint32 maxAlignment = 0; 1627 deUint32 curOffset = 0; 1628 1629 DE_ASSERT(layout != DE_NULL); 1630 DE_ASSERT(layout->empty()); 1631 layout->resize(symbols.size()); 1632 1633 for (size_t varNdx = 0; varNdx < symbols.size(); varNdx++) 1634 { 1635 const Symbol& symbol = symbols[varNdx]; 1636 const glu::DataType basicType = symbol.varType.getBasicType(); 1637 VarLayout& layoutEntry = (*layout)[varNdx]; 1638 1639 if (glu::isDataTypeScalarOrVector(basicType)) 1640 { 1641 const deUint32 alignment = getVecStd430ByteAlignment(basicType); 1642 const deUint32 size = (deUint32)glu::getDataTypeScalarSize(basicType) * (int)sizeof(deUint32); 1643 1644 curOffset = (deUint32)deAlign32((int)curOffset, (int)alignment); 1645 maxAlignment = de::max(maxAlignment, alignment); 1646 1647 layoutEntry.offset = curOffset; 1648 layoutEntry.matrixStride = 0; 1649 1650 curOffset += size; 1651 } 1652 else if (glu::isDataTypeMatrix(basicType)) 1653 { 1654 const int numVecs = glu::getDataTypeMatrixNumColumns(basicType); 1655 const glu::DataType vecType = glu::getDataTypeFloatVec(glu::getDataTypeMatrixNumRows(basicType)); 1656 const deUint32 vecAlignment = getVecStd430ByteAlignment(vecType); 1657 1658 curOffset = (deUint32)deAlign32((int)curOffset, (int)vecAlignment); 1659 maxAlignment = de::max(maxAlignment, vecAlignment); 1660 1661 layoutEntry.offset = curOffset; 1662 layoutEntry.matrixStride = vecAlignment; 1663 1664 curOffset += vecAlignment*numVecs; 1665 } 1666 else 1667 DE_ASSERT(false); 1668 } 1669 1670 { 1671 const deUint32 totalSize = (deUint32)deAlign32(curOffset, maxAlignment); 1672 1673 for (vector<VarLayout>::iterator varIter = layout->begin(); varIter != layout->end(); ++varIter) 1674 varIter->stride = totalSize; 1675 } 1676} 1677 1678void BufferIoExecutor::declareBufferBlocks (std::ostream& src, const ShaderSpec& spec) 1679{ 1680 // Input struct 1681 if (!spec.inputs.empty()) 1682 { 1683 glu::StructType inputStruct("Inputs"); 1684 for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter) 1685 inputStruct.addMember(symIter->name.c_str(), symIter->varType); 1686 src << glu::declare(&inputStruct) << ";\n"; 1687 } 1688 1689 // Output struct 1690 { 1691 glu::StructType outputStruct("Outputs"); 1692 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter) 1693 outputStruct.addMember(symIter->name.c_str(), symIter->varType); 1694 src << glu::declare(&outputStruct) << ";\n"; 1695 } 1696 1697 src << "\n"; 1698 1699 if (!spec.inputs.empty()) 1700 { 1701 src << "layout(set = 0, binding = " << int(INPUT_BUFFER_BINDING) << ", std430) buffer InBuffer\n" 1702 << "{\n" 1703 << " Inputs inputs[];\n" 1704 << "};\n"; 1705 } 1706 1707 src << "layout(set = 0, binding = " << int(OUTPUT_BUFFER_BINDING) << ", std430) buffer OutBuffer\n" 1708 << "{\n" 1709 << " Outputs outputs[];\n" 1710 << "};\n" 1711 << "\n"; 1712} 1713 1714void BufferIoExecutor::generateExecBufferIo (std::ostream& src, const ShaderSpec& spec, const char* invocationNdxName) 1715{ 1716 for (vector<Symbol>::const_iterator symIter = spec.inputs.begin(); symIter != spec.inputs.end(); ++symIter) 1717 src << "\t" << glu::declare(symIter->varType, symIter->name) << " = inputs[" << invocationNdxName << "]." << symIter->name << ";\n"; 1718 1719 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter) 1720 src << "\t" << glu::declare(symIter->varType, symIter->name) << ";\n"; 1721 1722 src << "\n"; 1723 1724 { 1725 std::istringstream opSrc (spec.source); 1726 std::string line; 1727 1728 while (std::getline(opSrc, line)) 1729 src << "\t" << line << "\n"; 1730 } 1731 1732 src << "\n"; 1733 for (vector<Symbol>::const_iterator symIter = spec.outputs.begin(); symIter != spec.outputs.end(); ++symIter) 1734 src << "\toutputs[" << invocationNdxName << "]." << symIter->name << " = " << symIter->name << ";\n"; 1735} 1736 1737void BufferIoExecutor::copyToBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr) 1738{ 1739 if (varType.isBasicType()) 1740 { 1741 const glu::DataType basicType = varType.getBasicType(); 1742 const bool isMatrix = glu::isDataTypeMatrix(basicType); 1743 const int scalarSize = glu::getDataTypeScalarSize(basicType); 1744 const int numVecs = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1; 1745 const int numComps = scalarSize / numVecs; 1746 1747 for (int elemNdx = 0; elemNdx < numValues; elemNdx++) 1748 { 1749 for (int vecNdx = 0; vecNdx < numVecs; vecNdx++) 1750 { 1751 const int srcOffset = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps); 1752 const int dstOffset = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0); 1753 const deUint8* srcPtr = (const deUint8*)srcBasePtr + srcOffset; 1754 deUint8* dstPtr = (deUint8*)dstBasePtr + dstOffset; 1755 1756 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps); 1757 } 1758 } 1759 } 1760 else 1761 throw tcu::InternalError("Unsupported type"); 1762} 1763 1764void BufferIoExecutor::copyFromBuffer (const glu::VarType& varType, const VarLayout& layout, int numValues, const void* srcBasePtr, void* dstBasePtr) 1765{ 1766 if (varType.isBasicType()) 1767 { 1768 const glu::DataType basicType = varType.getBasicType(); 1769 const bool isMatrix = glu::isDataTypeMatrix(basicType); 1770 const int scalarSize = glu::getDataTypeScalarSize(basicType); 1771 const int numVecs = isMatrix ? glu::getDataTypeMatrixNumColumns(basicType) : 1; 1772 const int numComps = scalarSize / numVecs; 1773 1774 for (int elemNdx = 0; elemNdx < numValues; elemNdx++) 1775 { 1776 for (int vecNdx = 0; vecNdx < numVecs; vecNdx++) 1777 { 1778 const int srcOffset = layout.offset + layout.stride * elemNdx + (isMatrix ? layout.matrixStride * vecNdx : 0); 1779 const int dstOffset = (int)sizeof(deUint32) * (elemNdx * scalarSize + vecNdx * numComps); 1780 const deUint8* srcPtr = (const deUint8*)srcBasePtr + srcOffset; 1781 deUint8* dstPtr = (deUint8*)dstBasePtr + dstOffset; 1782 1783 deMemcpy(dstPtr, srcPtr, sizeof(deUint32) * numComps); 1784 } 1785 } 1786 } 1787 else 1788 throw tcu::InternalError("Unsupported type"); 1789} 1790 1791void BufferIoExecutor::uploadInputBuffer (const Context& ctx, const void* const* inputPtrs, int numValues) 1792{ 1793 const VkDevice vkDevice = ctx.getDevice(); 1794 const DeviceInterface& vk = ctx.getDeviceInterface(); 1795 1796 const deUint32 inputStride = getLayoutStride(m_inputLayout); 1797 const int inputBufferSize = inputStride * numValues; 1798 1799 if (inputBufferSize == 0) 1800 return; // No inputs 1801 1802 DE_ASSERT(m_shaderSpec.inputs.size() == m_inputLayout.size()); 1803 for (size_t inputNdx = 0; inputNdx < m_shaderSpec.inputs.size(); ++inputNdx) 1804 { 1805 const glu::VarType& varType = m_shaderSpec.inputs[inputNdx].varType; 1806 const VarLayout& layout = m_inputLayout[inputNdx]; 1807 1808 copyToBuffer(varType, layout, numValues, inputPtrs[inputNdx], m_inputAlloc->getHostPtr()); 1809 } 1810 1811 flushMappedMemoryRange(vk, vkDevice, m_inputAlloc->getMemory(), m_inputAlloc->getOffset(), inputBufferSize); 1812} 1813 1814void BufferIoExecutor::readOutputBuffer (const Context& ctx, void* const* outputPtrs, int numValues) 1815{ 1816 const VkDevice vkDevice = ctx.getDevice(); 1817 const DeviceInterface& vk = ctx.getDeviceInterface(); 1818 1819 const deUint32 outputStride = getLayoutStride(m_outputLayout); 1820 const int outputBufferSize = numValues * outputStride; 1821 1822 DE_ASSERT(outputBufferSize > 0); // At least some outputs are required. 1823 1824 invalidateMappedMemoryRange(vk, vkDevice, m_outputAlloc->getMemory(), m_outputAlloc->getOffset(), outputBufferSize); 1825 1826 DE_ASSERT(m_shaderSpec.outputs.size() == m_outputLayout.size()); 1827 for (size_t outputNdx = 0; outputNdx < m_shaderSpec.outputs.size(); ++outputNdx) 1828 { 1829 const glu::VarType& varType = m_shaderSpec.outputs[outputNdx].varType; 1830 const VarLayout& layout = m_outputLayout[outputNdx]; 1831 1832 copyFromBuffer(varType, layout, numValues, m_outputAlloc->getHostPtr(), outputPtrs[outputNdx]); 1833 } 1834} 1835 1836void BufferIoExecutor::initBuffers (const Context& ctx, int numValues) 1837{ 1838 const deUint32 inputStride = getLayoutStride(m_inputLayout); 1839 const deUint32 outputStride = getLayoutStride(m_outputLayout); 1840 // Avoid creating zero-sized buffer/memory 1841 const size_t inputBufferSize = numValues * inputStride ? (numValues * inputStride) : 1; 1842 const size_t outputBufferSize = numValues * outputStride; 1843 1844 // Upload data to buffer 1845 const VkDevice vkDevice = ctx.getDevice(); 1846 const DeviceInterface& vk = ctx.getDeviceInterface(); 1847 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex(); 1848 Allocator& memAlloc = ctx.getDefaultAllocator(); 1849 1850 const VkBufferCreateInfo inputBufferParams = 1851 { 1852 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1853 DE_NULL, // const void* pNext; 1854 0u, // VkBufferCreateFlags flags; 1855 inputBufferSize, // VkDeviceSize size; 1856 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage; 1857 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1858 1u, // deUint32 queueFamilyCount; 1859 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 1860 }; 1861 1862 m_inputBuffer = createBuffer(vk, vkDevice, &inputBufferParams); 1863 m_inputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_inputBuffer), MemoryRequirement::HostVisible); 1864 1865 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_inputBuffer, m_inputAlloc->getMemory(), m_inputAlloc->getOffset())); 1866 1867 const VkBufferCreateInfo outputBufferParams = 1868 { 1869 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1870 DE_NULL, // const void* pNext; 1871 0u, // VkBufferCreateFlags flags; 1872 outputBufferSize, // VkDeviceSize size; 1873 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage; 1874 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1875 1u, // deUint32 queueFamilyCount; 1876 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 1877 }; 1878 1879 m_outputBuffer = createBuffer(vk, vkDevice, &outputBufferParams); 1880 m_outputAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_outputBuffer), MemoryRequirement::HostVisible); 1881 1882 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_outputBuffer, m_outputAlloc->getMemory(), m_outputAlloc->getOffset())); 1883} 1884 1885// ComputeShaderExecutor 1886 1887class ComputeShaderExecutor : public BufferIoExecutor 1888{ 1889public: 1890 ComputeShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType); 1891 virtual ~ComputeShaderExecutor (void); 1892 1893 virtual void setShaderSources (SourceCollections& programCollection) const; 1894 1895 virtual void execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs); 1896 1897protected: 1898 static std::string generateComputeShader (const ShaderSpec& spec); 1899}; 1900 1901ComputeShaderExecutor::ComputeShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType) 1902 : BufferIoExecutor (shaderSpec, shaderType) 1903{ 1904} 1905 1906ComputeShaderExecutor::~ComputeShaderExecutor (void) 1907{ 1908} 1909 1910std::string ComputeShaderExecutor::generateComputeShader (const ShaderSpec& spec) 1911{ 1912 std::ostringstream src; 1913 src << "#version 310 es\n"; 1914 1915 if (!spec.globalDeclarations.empty()) 1916 src << spec.globalDeclarations << "\n"; 1917 1918 src << "layout(local_size_x = 1) in;\n" 1919 << "\n"; 1920 1921 declareBufferBlocks(src, spec); 1922 1923 src << "void main (void)\n" 1924 << "{\n" 1925 << " uint invocationNdx = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z\n" 1926 << " + gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n"; 1927 1928 generateExecBufferIo(src, spec, "invocationNdx"); 1929 1930 src << "}\n"; 1931 1932 return src.str(); 1933} 1934 1935void ComputeShaderExecutor::setShaderSources (SourceCollections& programCollection) const 1936{ 1937 programCollection.glslSources.add("compute") << glu::ComputeSource(generateComputeShader(m_shaderSpec)); 1938} 1939 1940void ComputeShaderExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs) 1941{ 1942 checkSupported(ctx, m_shaderType); 1943 1944 const VkDevice vkDevice = ctx.getDevice(); 1945 const DeviceInterface& vk = ctx.getDeviceInterface(); 1946 const VkQueue queue = ctx.getUniversalQueue(); 1947 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex(); 1948 Allocator& memAlloc = ctx.getDefaultAllocator(); 1949 1950 Move<VkShaderModule> computeShaderModule; 1951 Move<VkPipeline> computePipeline; 1952 Move<VkPipelineLayout> pipelineLayout; 1953 Move<VkCommandPool> cmdPool; 1954 Move<VkDescriptorPool> descriptorPool; 1955 Move<VkDescriptorSetLayout> descriptorSetLayout; 1956 Move<VkDescriptorSet> descriptorSet; 1957 Move<VkFence> fence; 1958 1959 initBuffers(ctx, numValues); 1960 1961 // Setup input buffer & copy data 1962 uploadInputBuffer(ctx, inputs, numValues); 1963 1964 // Create command pool 1965 { 1966 const VkCommandPoolCreateInfo cmdPoolParams = 1967 { 1968 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 1969 DE_NULL, // const void* pNext; 1970 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags; 1971 queueFamilyIndex // deUint32 queueFamilyIndex; 1972 }; 1973 1974 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams); 1975 } 1976 1977 // Create command buffer 1978 const VkCommandBufferAllocateInfo cmdBufferParams = 1979 { 1980 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 1981 DE_NULL, // const void* pNext; 1982 *cmdPool, // VkCmdPool cmdPool; 1983 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level; 1984 1u // deUint32 bufferCount; 1985 }; 1986 1987 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1988 { 1989 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1990 DE_NULL, // const void* pNext; 1991 0u, // VkCmdBufferOptimizeFlags flags; 1992 (const VkCommandBufferInheritanceInfo*)DE_NULL, 1993 }; 1994 1995 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT); 1996 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); 1997 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT); 1998 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); 1999 2000 addUniforms(vkDevice, vk, queue, queueFamilyIndex, memAlloc); 2001 2002 descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice); 2003 descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 2004 2005 const VkDescriptorSetAllocateInfo allocInfo = 2006 { 2007 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 2008 DE_NULL, 2009 *descriptorPool, 2010 1u, 2011 &*descriptorSetLayout 2012 }; 2013 2014 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo); 2015 2016 // Create pipeline layout 2017 { 2018 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 2019 { 2020 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 2021 DE_NULL, // const void* pNext; 2022 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags; 2023 1u, // deUint32 CdescriptorSetCount; 2024 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts; 2025 0u, // deUint32 pushConstantRangeCount; 2026 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 2027 }; 2028 2029 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); 2030 } 2031 2032 // Create shaders 2033 { 2034 computeShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("compute"), 0); 2035 } 2036 2037 // create pipeline 2038 { 2039 const VkPipelineShaderStageCreateInfo shaderStageParams[1] = 2040 { 2041 { 2042 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 2043 DE_NULL, // const void* pNext; 2044 (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags; 2045 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagsBit stage; 2046 *computeShaderModule, // VkShaderModule shader; 2047 "main", // const char* pName; 2048 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 2049 } 2050 }; 2051 2052 const VkComputePipelineCreateInfo computePipelineParams = 2053 { 2054 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType; 2055 DE_NULL, // const void* pNext; 2056 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags; 2057 *shaderStageParams, // VkPipelineShaderStageCreateInfo cs; 2058 *pipelineLayout, // VkPipelineLayout layout; 2059 0u, // VkPipeline basePipelineHandle; 2060 0u, // int32_t basePipelineIndex; 2061 }; 2062 2063 computePipeline = createComputePipeline(vk, vkDevice, DE_NULL, &computePipelineParams); 2064 } 2065 2066 // Create fence 2067 { 2068 const VkFenceCreateInfo fenceParams = 2069 { 2070 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 2071 DE_NULL, // const void* pNext; 2072 0u // VkFenceCreateFlags flags; 2073 }; 2074 fence = createFence(vk, vkDevice, &fenceParams); 2075 } 2076 2077 const int maxValuesPerInvocation = ctx.getDeviceProperties().limits.maxComputeWorkGroupSize[0]; 2078 int curOffset = 0; 2079 const deUint32 inputStride = getInputStride(); 2080 const deUint32 outputStride = getOutputStride(); 2081 2082 while (curOffset < numValues) 2083 { 2084 Move<VkCommandBuffer> cmdBuffer; 2085 const int numToExec = de::min(maxValuesPerInvocation, numValues-curOffset); 2086 2087 // Update descriptors 2088 { 2089 DescriptorSetUpdateBuilder descriptorSetUpdateBuilder; 2090 2091 const VkDescriptorBufferInfo outputDescriptorBufferInfo = 2092 { 2093 *m_outputBuffer, // VkBuffer buffer; 2094 curOffset * outputStride, // VkDeviceSize offset; 2095 numToExec * outputStride // VkDeviceSize range; 2096 }; 2097 2098 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo); 2099 2100 if (inputStride) 2101 { 2102 const VkDescriptorBufferInfo inputDescriptorBufferInfo = 2103 { 2104 *m_inputBuffer, // VkBuffer buffer; 2105 curOffset * inputStride, // VkDeviceSize offset; 2106 numToExec * inputStride // VkDeviceSize range; 2107 }; 2108 2109 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo); 2110 } 2111 2112 uploadUniforms(descriptorSetUpdateBuilder, *descriptorSet); 2113 2114 descriptorSetUpdateBuilder.update(vk, vkDevice); 2115 } 2116 2117 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams); 2118 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); 2119 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline); 2120 2121 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL); 2122 2123 vk.cmdDispatch(*cmdBuffer, numToExec, 1, 1); 2124 2125 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 2126 2127 curOffset += numToExec; 2128 2129 // Execute 2130 { 2131 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get())); 2132 2133 const VkSubmitInfo submitInfo = 2134 { 2135 VK_STRUCTURE_TYPE_SUBMIT_INFO, 2136 DE_NULL, 2137 0u, 2138 (const VkSemaphore*)DE_NULL, 2139 (const VkPipelineStageFlags*)DE_NULL, 2140 1u, 2141 &cmdBuffer.get(), 2142 0u, 2143 (const VkSemaphore*)DE_NULL, 2144 }; 2145 2146 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 2147 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/)); 2148 } 2149 } 2150 2151 // Read back data 2152 readOutputBuffer(ctx, outputs, numValues); 2153} 2154 2155// Tessellation utils 2156 2157static std::string generateVertexShaderForTess (void) 2158{ 2159 std::ostringstream src; 2160 src << "#version 310 es\n" 2161 << "void main (void)\n{\n" 2162 << " gl_Position = vec4(gl_VertexIndex/2, gl_VertexIndex%2, 0.0, 1.0);\n" 2163 << "}\n"; 2164 2165 return src.str(); 2166} 2167 2168class TessellationExecutor : public BufferIoExecutor 2169{ 2170public: 2171 TessellationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType); 2172 virtual ~TessellationExecutor (void); 2173 2174 void renderTess (const Context& ctx, deUint32 numValues, deUint32 vertexCount, deUint32 patchControlPoints); 2175}; 2176 2177TessellationExecutor::TessellationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType) 2178 : BufferIoExecutor (shaderSpec, shaderType) 2179{ 2180} 2181 2182TessellationExecutor::~TessellationExecutor (void) 2183{ 2184} 2185 2186void TessellationExecutor::renderTess (const Context& ctx, deUint32 numValues, deUint32 vertexCount, deUint32 patchControlPoints) 2187{ 2188 const size_t inputBufferSize = numValues * getInputStride(); 2189 const VkDevice vkDevice = ctx.getDevice(); 2190 const DeviceInterface& vk = ctx.getDeviceInterface(); 2191 const VkQueue queue = ctx.getUniversalQueue(); 2192 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex(); 2193 Allocator& memAlloc = ctx.getDefaultAllocator(); 2194 2195 const tcu::UVec2 renderSize (DEFAULT_RENDER_WIDTH, DEFAULT_RENDER_HEIGHT); 2196 2197 Move<VkImage> colorImage; 2198 de::MovePtr<Allocation> colorImageAlloc; 2199 VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM; 2200 Move<VkImageView> colorImageView; 2201 2202 Move<VkRenderPass> renderPass; 2203 Move<VkFramebuffer> framebuffer; 2204 Move<VkPipelineLayout> pipelineLayout; 2205 Move<VkPipeline> graphicsPipeline; 2206 2207 Move<VkShaderModule> vertexShaderModule; 2208 Move<VkShaderModule> tessControlShaderModule; 2209 Move<VkShaderModule> tessEvalShaderModule; 2210 Move<VkShaderModule> fragmentShaderModule; 2211 2212 Move<VkCommandPool> cmdPool; 2213 Move<VkCommandBuffer> cmdBuffer; 2214 2215 Move<VkFence> fence; 2216 2217 Move<VkDescriptorPool> descriptorPool; 2218 Move<VkDescriptorSetLayout> descriptorSetLayout; 2219 Move<VkDescriptorSet> descriptorSet; 2220 2221 // Create color image 2222 { 2223 const VkImageCreateInfo colorImageParams = 2224 { 2225 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 2226 DE_NULL, // const void* pNext; 2227 0u, // VkImageCreateFlags flags; 2228 VK_IMAGE_TYPE_2D, // VkImageType imageType; 2229 colorFormat, // VkFormat format; 2230 { renderSize.x(), renderSize.y(), 1u }, // VkExtent3D extent; 2231 1u, // deUint32 mipLevels; 2232 1u, // deUint32 arraySize; 2233 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 2234 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 2235 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; 2236 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 2237 1u, // deUint32 queueFamilyCount; 2238 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 2239 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 2240 }; 2241 2242 colorImage = createImage(vk, vkDevice, &colorImageParams); 2243 2244 // Allocate and bind color image memory 2245 colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *colorImage), MemoryRequirement::Any); 2246 VK_CHECK(vk.bindImageMemory(vkDevice, *colorImage, colorImageAlloc->getMemory(), colorImageAlloc->getOffset())); 2247 } 2248 2249 // Create color attachment view 2250 { 2251 const VkImageViewCreateInfo colorImageViewParams = 2252 { 2253 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 2254 DE_NULL, // const void* pNext; 2255 0u, // VkImageViewCreateFlags flags; 2256 *colorImage, // VkImage image; 2257 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 2258 colorFormat, // VkFormat format; 2259 { 2260 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r; 2261 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g; 2262 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b; 2263 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a; 2264 }, // VkComponentsMapping components; 2265 { 2266 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 2267 0u, // deUint32 baseMipLevel; 2268 1u, // deUint32 mipLevels; 2269 0u, // deUint32 baseArraylayer; 2270 1u // deUint32 layerCount; 2271 } // VkImageSubresourceRange subresourceRange; 2272 }; 2273 2274 colorImageView = createImageView(vk, vkDevice, &colorImageViewParams); 2275 } 2276 2277 // Create render pass 2278 { 2279 const VkAttachmentDescription colorAttachmentDescription = 2280 { 2281 0u, // VkAttachmentDescriptorFlags flags; 2282 colorFormat, // VkFormat format; 2283 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 2284 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 2285 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 2286 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 2287 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 2288 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 2289 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout 2290 }; 2291 2292 const VkAttachmentDescription attachments[1] = 2293 { 2294 colorAttachmentDescription 2295 }; 2296 2297 const VkAttachmentReference colorAttachmentReference = 2298 { 2299 0u, // deUint32 attachment; 2300 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 2301 }; 2302 2303 const VkSubpassDescription subpassDescription = 2304 { 2305 0u, // VkSubpassDescriptionFlags flags; 2306 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 2307 0u, // deUint32 inputCount; 2308 DE_NULL, // const VkAttachmentReference* pInputAttachments; 2309 1u, // deUint32 colorCount; 2310 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments; 2311 DE_NULL, // const VkAttachmentReference* pResolveAttachments; 2312 DE_NULL, // VkAttachmentReference depthStencilAttachment; 2313 0u, // deUint32 preserveCount; 2314 DE_NULL // const VkAttachmentReference* pPreserveAttachments; 2315 }; 2316 2317 const VkRenderPassCreateInfo renderPassParams = 2318 { 2319 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 2320 DE_NULL, // const void* pNext; 2321 0u, // VkRenderPassCreateFlags flags; 2322 1u, // deUint32 attachmentCount; 2323 attachments, // const VkAttachmentDescription* pAttachments; 2324 1u, // deUint32 subpassCount; 2325 &subpassDescription, // const VkSubpassDescription* pSubpasses; 2326 0u, // deUint32 dependencyCount; 2327 DE_NULL // const VkSubpassDependency* pDependencies; 2328 }; 2329 2330 renderPass = createRenderPass(vk, vkDevice, &renderPassParams); 2331 } 2332 2333 // Create framebuffer 2334 { 2335 const VkFramebufferCreateInfo framebufferParams = 2336 { 2337 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 2338 DE_NULL, // const void* pNext; 2339 0u, // VkFramebufferCreateFlags flags; 2340 *renderPass, // VkRenderPass renderPass; 2341 1u, // deUint32 attachmentCount; 2342 &*colorImageView, // const VkAttachmentBindInfo* pAttachments; 2343 (deUint32)renderSize.x(), // deUint32 width; 2344 (deUint32)renderSize.y(), // deUint32 height; 2345 1u // deUint32 layers; 2346 }; 2347 2348 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams); 2349 } 2350 2351 // Create descriptors 2352 { 2353 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL); 2354 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); 2355 m_descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL); 2356 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); 2357 2358 addUniforms(vkDevice, vk, queue, queueFamilyIndex, memAlloc); 2359 2360 descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice); 2361 descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 2362 2363 const VkDescriptorSetAllocateInfo allocInfo = 2364 { 2365 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 2366 DE_NULL, 2367 *descriptorPool, 2368 1u, 2369 &*descriptorSetLayout 2370 }; 2371 2372 descriptorSet = allocateDescriptorSet(vk, vkDevice, &allocInfo); 2373 // Update descriptors 2374 { 2375 DescriptorSetUpdateBuilder descriptorSetUpdateBuilder; 2376 const VkDescriptorBufferInfo outputDescriptorBufferInfo = 2377 { 2378 *m_outputBuffer, // VkBuffer buffer; 2379 0u, // VkDeviceSize offset; 2380 VK_WHOLE_SIZE // VkDeviceSize range; 2381 }; 2382 2383 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)OUTPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputDescriptorBufferInfo); 2384 2385 VkDescriptorBufferInfo inputDescriptorBufferInfo = 2386 { 2387 0, // VkBuffer buffer; 2388 0u, // VkDeviceSize offset; 2389 VK_WHOLE_SIZE // VkDeviceSize range; 2390 }; 2391 2392 if (inputBufferSize > 0) 2393 { 2394 inputDescriptorBufferInfo.buffer = *m_inputBuffer; 2395 2396 descriptorSetUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding((deUint32)INPUT_BUFFER_BINDING), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputDescriptorBufferInfo); 2397 } 2398 2399 uploadUniforms(descriptorSetUpdateBuilder, *descriptorSet); 2400 2401 descriptorSetUpdateBuilder.update(vk, vkDevice); 2402 } 2403 } 2404 2405 // Create pipeline layout 2406 { 2407 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 2408 { 2409 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 2410 DE_NULL, // const void* pNext; 2411 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags; 2412 1u, // deUint32 descriptorSetCount; 2413 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts; 2414 0u, // deUint32 pushConstantRangeCount; 2415 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 2416 }; 2417 2418 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); 2419 } 2420 2421 // Create shader modules 2422 { 2423 vertexShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("vert"), 0); 2424 tessControlShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("tess_control"), 0); 2425 tessEvalShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("tess_eval"), 0); 2426 fragmentShaderModule = createShaderModule(vk, vkDevice, ctx.getBinaryCollection().get("frag"), 0); 2427 } 2428 2429 // Create pipeline 2430 { 2431 const VkPipelineShaderStageCreateInfo shaderStageParams[4] = 2432 { 2433 { 2434 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 2435 DE_NULL, // const void* pNext; 2436 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 2437 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBit stage; 2438 *vertexShaderModule, // VkShaderModule shader; 2439 "main", // const char* pName; 2440 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 2441 }, 2442 { 2443 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 2444 DE_NULL, // const void* pNext; 2445 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 2446 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, // VkShaderStageFlagBit stage; 2447 *tessControlShaderModule, // VkShaderModule shader; 2448 "main", // const char* pName; 2449 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 2450 }, 2451 { 2452 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 2453 DE_NULL, // const void* pNext; 2454 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 2455 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, // VkShaderStageFlagBit stage; 2456 *tessEvalShaderModule, // VkShaderModule shader; 2457 "main", // const char* pName; 2458 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 2459 }, 2460 { 2461 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 2462 DE_NULL, // const void* pNext; 2463 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 2464 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBit stage; 2465 *fragmentShaderModule, // VkShaderModule shader; 2466 "main", // const char* pName; 2467 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 2468 } 2469 }; 2470 2471 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 2472 { 2473 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 2474 DE_NULL, // const void* pNext; 2475 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags; 2476 0u, // deUint32 bindingCount; 2477 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 2478 0u, // deUint32 attributeCount; 2479 DE_NULL, // const VkVertexInputAttributeDescription* pvertexAttributeDescriptions; 2480 }; 2481 2482 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = 2483 { 2484 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 2485 DE_NULL, // const void* pNext; 2486 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 2487 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, // VkPrimitiveTopology topology; 2488 DE_FALSE // VkBool32 primitiveRestartEnable; 2489 }; 2490 2491 struct VkPipelineTessellationStateCreateInfo tessellationStateParams = 2492 { 2493 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType; 2494 DE_NULL, // const void* pNext; 2495 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags; 2496 patchControlPoints // uint32_t patchControlPoints; 2497 }; 2498 2499 const VkViewport viewport = 2500 { 2501 0.0f, // float originX; 2502 0.0f, // float originY; 2503 (float)renderSize.x(), // float width; 2504 (float)renderSize.y(), // float height; 2505 0.0f, // float minDepth; 2506 1.0f // float maxDepth; 2507 }; 2508 2509 const VkRect2D scissor = 2510 { 2511 { 2512 0u, // deUint32 x; 2513 0u, // deUint32 y; 2514 }, // VkOffset2D offset; 2515 { 2516 renderSize.x(), // deUint32 width; 2517 renderSize.y(), // deUint32 height; 2518 }, // VkExtent2D extent; 2519 }; 2520 2521 const VkPipelineViewportStateCreateInfo viewportStateParams = 2522 { 2523 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 2524 DE_NULL, // const void* pNext; 2525 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewPortStateCreateFlags flags; 2526 1u, // deUint32 viewportCount; 2527 &viewport, // const VkViewport* pViewports; 2528 1u, // deUint32 scissorsCount; 2529 &scissor // const VkRect2D* pScissors; 2530 }; 2531 2532 const VkPipelineRasterizationStateCreateInfo rasterStateParams = 2533 { 2534 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 2535 DE_NULL, // const void* pNext; 2536 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStageCreateFlags flags; 2537 VK_FALSE, // VkBool32 depthClipEnable; 2538 VK_FALSE, // VkBool32 rasterizerDiscardEnable; 2539 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 2540 VK_CULL_MODE_NONE, // VkCullMode cullMode; 2541 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 2542 VK_FALSE, // VkBool32 depthBiasEnable; 2543 0.0f, // float depthBias; 2544 0.0f, // float depthBiasClamp; 2545 0.0f, // float slopeScaledDepthBias; 2546 1.0f // float lineWidth; 2547 }; 2548 2549 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 2550 { 2551 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 2552 DE_NULL, // const void* pNext; 2553 0u, // VkPipelineMultisampleStateCreateFlags flags; 2554 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 2555 VK_FALSE, // VkBool32 sampleShadingEnable; 2556 0.0f, // float minSampleShading; 2557 DE_NULL, // const VkSampleMask* pSampleMask; 2558 VK_FALSE, // VkBool32 alphaToCoverageEnable; 2559 VK_FALSE // VkBool32 alphaToOneEnable; 2560 }; 2561 2562 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = 2563 { 2564 VK_FALSE, // VkBool32 blendEnable; 2565 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcBlendColor; 2566 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destBlendColor; 2567 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor; 2568 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcBlendAlpha; 2569 VK_BLEND_FACTOR_ZERO, // VkBlendFactor destBlendAlpha; 2570 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha; 2571 (VK_COLOR_COMPONENT_R_BIT | 2572 VK_COLOR_COMPONENT_G_BIT | 2573 VK_COLOR_COMPONENT_B_BIT | 2574 VK_COLOR_COMPONENT_A_BIT) // VkColorComponentFlags colorWriteMask; 2575 }; 2576 2577 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 2578 { 2579 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 2580 DE_NULL, // const void* pNext; 2581 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags 2582 VK_FALSE, // VkBool32 logicOpEnable; 2583 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 2584 1u, // deUint32 attachmentCount; 2585 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 2586 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConst[4]; 2587 }; 2588 2589 const VkGraphicsPipelineCreateInfo graphicsPipelineParams = 2590 { 2591 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 2592 DE_NULL, // const void* pNext; 2593 0u, // VkPipelineCreateFlags flags; 2594 4u, // deUint32 stageCount; 2595 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages; 2596 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 2597 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 2598 &tessellationStateParams, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 2599 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; 2600 &rasterStateParams, // const VkPipelineRasterStateCreateInfo* pRasterState; 2601 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 2602 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 2603 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 2604 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 2605 *pipelineLayout, // VkPipelineLayout layout; 2606 *renderPass, // VkRenderPass renderPass; 2607 0u, // deUint32 subpass; 2608 0u, // VkPipeline basePipelineHandle; 2609 0u // deInt32 basePipelineIndex; 2610 }; 2611 2612 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams); 2613 } 2614 2615 // Create command pool 2616 { 2617 const VkCommandPoolCreateInfo cmdPoolParams = 2618 { 2619 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 2620 DE_NULL, // const void* pNext; 2621 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags; 2622 queueFamilyIndex, // deUint32 queueFamilyIndex; 2623 }; 2624 2625 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams); 2626 } 2627 2628 // Create command buffer 2629 { 2630 const VkCommandBufferAllocateInfo cmdBufferParams = 2631 { 2632 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 2633 DE_NULL, // const void* pNext; 2634 *cmdPool, // VkCmdPool cmdPool; 2635 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level; 2636 1u // uint32_t bufferCount; 2637 }; 2638 2639 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 2640 { 2641 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 2642 DE_NULL, // const void* pNext; 2643 0u, // VkCmdBufferOptimizeFlags flags; 2644 (const VkCommandBufferInheritanceInfo*)DE_NULL, 2645 }; 2646 2647 const VkClearValue clearValues[1] = 2648 { 2649 getDefaultClearColor() 2650 }; 2651 2652 const VkRenderPassBeginInfo renderPassBeginInfo = 2653 { 2654 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 2655 DE_NULL, // const void* pNext; 2656 *renderPass, // VkRenderPass renderPass; 2657 *framebuffer, // VkFramebuffer framebuffer; 2658 { { 0, 0 }, { renderSize.x(), renderSize.y() } }, // VkRect2D renderArea; 2659 1, // deUint32 attachmentCount; 2660 clearValues // const VkClearValue* pClearValues; 2661 }; 2662 2663 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferParams); 2664 2665 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); 2666 2667 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 2668 2669 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline); 2670 2671 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL); 2672 2673 vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0); 2674 2675 vk.cmdEndRenderPass(*cmdBuffer); 2676 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 2677 } 2678 2679 // Create fence 2680 { 2681 const VkFenceCreateInfo fenceParams = 2682 { 2683 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 2684 DE_NULL, // const void* pNext; 2685 0u // VkFenceCreateFlags flags; 2686 }; 2687 fence = createFence(vk, vkDevice, &fenceParams); 2688 } 2689 2690 // Execute Draw 2691 { 2692 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get())); 2693 const VkSubmitInfo submitInfo = 2694 { 2695 VK_STRUCTURE_TYPE_SUBMIT_INFO, 2696 DE_NULL, 2697 0u, 2698 (const VkSemaphore*)0, 2699 (const VkPipelineStageFlags*)DE_NULL, 2700 1u, 2701 &cmdBuffer.get(), 2702 0u, 2703 (const VkSemaphore*)0, 2704 }; 2705 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 2706 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity*/)); 2707 } 2708} 2709 2710// TessControlExecutor 2711 2712class TessControlExecutor : public TessellationExecutor 2713{ 2714public: 2715 TessControlExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType); 2716 virtual ~TessControlExecutor (void); 2717 2718 virtual void setShaderSources (SourceCollections& programCollection) const; 2719 2720 virtual void execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs); 2721 2722protected: 2723 static std::string generateTessControlShader (const ShaderSpec& shaderSpec); 2724}; 2725 2726TessControlExecutor::TessControlExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType) 2727 : TessellationExecutor (shaderSpec, shaderType) 2728{ 2729} 2730 2731TessControlExecutor::~TessControlExecutor (void) 2732{ 2733} 2734 2735std::string TessControlExecutor::generateTessControlShader (const ShaderSpec& shaderSpec) 2736{ 2737 std::ostringstream src; 2738 src << "#version 310 es\n" 2739 "#extension GL_EXT_tessellation_shader : require\n\n"; 2740 2741 if (!shaderSpec.globalDeclarations.empty()) 2742 src << shaderSpec.globalDeclarations << "\n"; 2743 2744 src << "\nlayout(vertices = 1) out;\n\n"; 2745 2746 declareBufferBlocks(src, shaderSpec); 2747 2748 src << "void main (void)\n{\n"; 2749 2750 for (int ndx = 0; ndx < 2; ndx++) 2751 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n"; 2752 2753 for (int ndx = 0; ndx < 4; ndx++) 2754 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n"; 2755 2756 src << "\n" 2757 << "\thighp uint invocationId = uint(gl_PrimitiveID);\n"; 2758 2759 generateExecBufferIo(src, shaderSpec, "invocationId"); 2760 2761 src << "}\n"; 2762 2763 return src.str(); 2764} 2765 2766static std::string generateEmptyTessEvalShader () 2767{ 2768 std::ostringstream src; 2769 2770 src << "#version 310 es\n" 2771 "#extension GL_EXT_tessellation_shader : require\n\n"; 2772 2773 src << "layout(triangles, ccw) in;\n"; 2774 2775 src << "\nvoid main (void)\n{\n" 2776 << "\tgl_Position = vec4(gl_TessCoord.xy, 0.0, 1.0);\n" 2777 << "}\n"; 2778 2779 return src.str(); 2780} 2781 2782void TessControlExecutor::setShaderSources (SourceCollections& programCollection) const 2783{ 2784 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess()); 2785 programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generateTessControlShader(m_shaderSpec)); 2786 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateEmptyTessEvalShader()); 2787 programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource()); 2788} 2789 2790void TessControlExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs) 2791{ 2792 const deUint32 patchSize = 3; 2793 2794 checkSupported(ctx, m_shaderType); 2795 2796 initBuffers(ctx, numValues); 2797 2798 // Setup input buffer & copy data 2799 uploadInputBuffer(ctx, inputs, numValues); 2800 2801 renderTess(ctx, numValues, patchSize * numValues, patchSize); 2802 2803 // Read back data 2804 readOutputBuffer(ctx, outputs, numValues); 2805} 2806 2807// TessEvaluationExecutor 2808 2809class TessEvaluationExecutor : public TessellationExecutor 2810{ 2811public: 2812 TessEvaluationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType); 2813 virtual ~TessEvaluationExecutor (void); 2814 2815 virtual void setShaderSources (SourceCollections& programCollection) const; 2816 2817 virtual void execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs); 2818 2819protected: 2820 static std::string generateTessEvalShader (const ShaderSpec& shaderSpec); 2821}; 2822 2823TessEvaluationExecutor::TessEvaluationExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType) 2824 : TessellationExecutor (shaderSpec, shaderType) 2825{ 2826} 2827 2828TessEvaluationExecutor::~TessEvaluationExecutor (void) 2829{ 2830} 2831 2832static std::string generatePassthroughTessControlShader (void) 2833{ 2834 std::ostringstream src; 2835 2836 src << "#version 310 es\n" 2837 "#extension GL_EXT_tessellation_shader : require\n\n"; 2838 2839 src << "layout(vertices = 1) out;\n\n"; 2840 2841 src << "void main (void)\n{\n"; 2842 2843 for (int ndx = 0; ndx < 2; ndx++) 2844 src << "\tgl_TessLevelInner[" << ndx << "] = 1.0;\n"; 2845 2846 for (int ndx = 0; ndx < 4; ndx++) 2847 src << "\tgl_TessLevelOuter[" << ndx << "] = 1.0;\n"; 2848 2849 src << "}\n"; 2850 2851 return src.str(); 2852} 2853 2854std::string TessEvaluationExecutor::generateTessEvalShader (const ShaderSpec& shaderSpec) 2855{ 2856 std::ostringstream src; 2857 2858 src << "#version 310 es\n" 2859 "#extension GL_EXT_tessellation_shader : require\n\n"; 2860 2861 if (!shaderSpec.globalDeclarations.empty()) 2862 src << shaderSpec.globalDeclarations << "\n"; 2863 2864 src << "\n"; 2865 2866 src << "layout(isolines, equal_spacing) in;\n\n"; 2867 2868 declareBufferBlocks(src, shaderSpec); 2869 2870 src << "void main (void)\n{\n" 2871 << "\tgl_Position = vec4(gl_TessCoord.x, 0.0, 0.0, 1.0);\n" 2872 << "\thighp uint invocationId = uint(gl_PrimitiveID)*2u + (gl_TessCoord.x > 0.5 ? 1u : 0u);\n"; 2873 2874 generateExecBufferIo(src, shaderSpec, "invocationId"); 2875 2876 src << "}\n"; 2877 2878 return src.str(); 2879} 2880 2881void TessEvaluationExecutor::setShaderSources (SourceCollections& programCollection) const 2882{ 2883 programCollection.glslSources.add("vert") << glu::VertexSource(generateVertexShaderForTess()); 2884 programCollection.glslSources.add("tess_control") << glu::TessellationControlSource(generatePassthroughTessControlShader()); 2885 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(generateTessEvalShader(m_shaderSpec)); 2886 programCollection.glslSources.add("frag") << glu::FragmentSource(generateEmptyFragmentSource()); 2887} 2888 2889void TessEvaluationExecutor::execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs) 2890{ 2891 checkSupported(ctx, m_shaderType); 2892 2893 const int patchSize = 2; 2894 const int alignedValues = deAlign32(numValues, patchSize); 2895 2896 // Initialize buffers with aligned value count to make room for padding 2897 initBuffers(ctx, alignedValues); 2898 2899 // Setup input buffer & copy data 2900 uploadInputBuffer(ctx, inputs, numValues); 2901 2902 renderTess(ctx, (deUint32)alignedValues, (deUint32)alignedValues, (deUint32)patchSize); 2903 2904 // Read back data 2905 readOutputBuffer(ctx, outputs, numValues); 2906} 2907 2908} // anonymous 2909 2910// ShaderExecutor 2911 2912ShaderExecutor::ShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType) 2913 : m_shaderSpec (shaderSpec) 2914 , m_shaderType (shaderType) 2915{ 2916} 2917 2918ShaderExecutor::~ShaderExecutor (void) 2919{ 2920} 2921 2922// Utilities 2923 2924ShaderExecutor* createExecutor (glu::ShaderType shaderType, const ShaderSpec& shaderSpec) 2925{ 2926 switch (shaderType) 2927 { 2928 case glu::SHADERTYPE_VERTEX: return new VertexShaderExecutor (shaderSpec, shaderType); 2929 case glu::SHADERTYPE_TESSELLATION_CONTROL: return new TessControlExecutor (shaderSpec, shaderType); 2930 case glu::SHADERTYPE_TESSELLATION_EVALUATION: return new TessEvaluationExecutor (shaderSpec, shaderType); 2931 case glu::SHADERTYPE_GEOMETRY: return new GeometryShaderExecutor (shaderSpec, shaderType); 2932 case glu::SHADERTYPE_FRAGMENT: return new FragmentShaderExecutor (shaderSpec, shaderType); 2933 case glu::SHADERTYPE_COMPUTE: return new ComputeShaderExecutor (shaderSpec, shaderType); 2934 default: 2935 throw tcu::InternalError("Unsupported shader type"); 2936 } 2937} 2938 2939de::MovePtr<ShaderExecutor::BufferUniform> ShaderExecutor::createBufferUniform (const VkDevice& vkDevice, 2940 const DeviceInterface& vk, 2941 const VkQueue /*queue*/, 2942 const deUint32 queueFamilyIndex, 2943 Allocator& memAlloc, 2944 deUint32 bindingLocation, 2945 VkDescriptorType descriptorType, 2946 deUint32 size, 2947 const void* dataPtr) 2948{ 2949 DE_ASSERT(descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); 2950 2951 VkImageUsageFlags usage = descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; 2952 2953 const VkBufferCreateInfo uniformBufferParams = 2954 { 2955 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 2956 DE_NULL, // const void* pNext; 2957 0u, // VkBufferCreateFlags flags; 2958 size, // VkDeviceSize size; 2959 usage, // VkBufferUsageFlags usage; 2960 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 2961 1u, // deUint32 queueFamilyIndexCount; 2962 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 2963 }; 2964 2965 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &uniformBufferParams); 2966 de::MovePtr<Allocation> alloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible); 2967 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), alloc->getOffset())); 2968 2969 deMemcpy(alloc->getHostPtr(), dataPtr, size); 2970 flushMappedMemoryRange(vk, vkDevice, alloc->getMemory(), alloc->getOffset(), size); 2971 2972 de::MovePtr<BufferUniform> uniformInfo(new BufferUniform()); 2973 uniformInfo->type = descriptorType; 2974 uniformInfo->descriptor = makeDescriptorBufferInfo(*buffer, 0u, size); 2975 uniformInfo->location = bindingLocation; 2976 uniformInfo->buffer = VkBufferSp(new Unique<VkBuffer>(buffer)); 2977 uniformInfo->alloc = AllocationSp(alloc.release()); 2978 2979 return uniformInfo; 2980} 2981 2982void ShaderExecutor::setupUniformData (const VkDevice& vkDevice, 2983 const DeviceInterface& vk, 2984 const VkQueue queue, 2985 const deUint32 queueFamilyIndex, 2986 Allocator& memAlloc, 2987 deUint32 bindingLocation, 2988 VkDescriptorType descriptorType, 2989 deUint32 size, 2990 const void* dataPtr) 2991{ 2992 de::MovePtr<BufferUniform> uniform = createBufferUniform(vkDevice, vk, queue, queueFamilyIndex, memAlloc, bindingLocation, descriptorType, size, dataPtr); 2993 2994 m_descriptorSetLayoutBuilder.addSingleBinding(descriptorType, VK_SHADER_STAGE_ALL); 2995 m_descriptorPoolBuilder.addType(descriptorType); 2996 2997 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(uniform))); 2998} 2999 3000void ShaderExecutor::setupUniformArray (const VkDevice& vkDevice, 3001 const DeviceInterface& vk, 3002 const VkQueue queue, 3003 const deUint32 queueFamilyIndex, 3004 Allocator& memAlloc, 3005 deUint32 bindingLocation, 3006 VkDescriptorType descriptorType, 3007 deUint32 arraySize, 3008 deUint32 size, 3009 const void* dataPtr) 3010{ 3011 DE_ASSERT(arraySize > 0); 3012 3013 de::MovePtr<BufferArrayUniform> bufferArray (new BufferArrayUniform()); 3014 3015 bufferArray->type = descriptorType; 3016 bufferArray->location = bindingLocation; 3017 3018 for (deUint32 ndx = 0; ndx < arraySize; ++ndx) 3019 { 3020 const void* bufferData = ((deUint8*)dataPtr) + (ndx * size); 3021 de::MovePtr<BufferUniform> uniform = createBufferUniform(vkDevice, vk, queue, queueFamilyIndex, memAlloc, bindingLocation, descriptorType, size, bufferData); 3022 3023 bufferArray->uniforms.push_back(BufferUniformSp(new de::UniquePtr<BufferUniform>(uniform))); 3024 } 3025 3026 m_descriptorSetLayoutBuilder.addArrayBinding(descriptorType, arraySize, VK_SHADER_STAGE_ALL); 3027 m_descriptorPoolBuilder.addType(descriptorType, arraySize); 3028 3029 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(bufferArray))); 3030} 3031 3032void ShaderExecutor::setupSamplerData (const VkDevice& vkDevice, 3033 const DeviceInterface& vk, 3034 const VkQueue queue, 3035 const deUint32 queueFamilyIndex, 3036 Allocator& memAlloc, 3037 deUint32 bindingLocation, 3038 deUint32 numSamplers, 3039 const tcu::Sampler& refSampler, 3040 const tcu::TextureFormat& texFormat, 3041 const tcu::IVec3& texSize, 3042 VkImageType imageType, 3043 VkImageViewType imageViewType, 3044 const void* data) 3045{ 3046 DE_ASSERT(numSamplers > 0); 3047 3048 de::MovePtr<SamplerArrayUniform> samplers (new SamplerArrayUniform()); 3049 3050 samplers->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 3051 samplers->location = bindingLocation; 3052 3053 for (deUint32 ndx = 0; ndx < numSamplers; ++ndx) 3054 { 3055 const int offset = ndx * texSize.x() * texSize.y() * texSize.z() * texFormat.getPixelSize(); 3056 const void* samplerData = ((deUint8*)data) + offset; 3057 de::MovePtr<SamplerUniform> uniform = createSamplerUniform(vkDevice, vk, queue, queueFamilyIndex, memAlloc, bindingLocation, refSampler, texFormat, texSize, imageType, imageViewType, samplerData); 3058 3059 samplers->uniforms.push_back(SamplerUniformSp(new de::UniquePtr<SamplerUniform>(uniform))); 3060 } 3061 3062 m_descriptorSetLayoutBuilder.addArraySamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, numSamplers, VK_SHADER_STAGE_ALL, DE_NULL); 3063 m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, numSamplers); 3064 3065 m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(samplers))); 3066} 3067 3068const void* ShaderExecutor::getBufferPtr (const deUint32 bindingLocation) const 3069{ 3070 std::vector<UniformInfoSp>::const_iterator it = m_uniformInfos.begin(); 3071 for (; it != m_uniformInfos.end(); it++) 3072 { 3073 const UniformInfo* uniformInfo = it->get()->get(); 3074 if (uniformInfo->getType() == UniformInfo::UNIFORM_TYPE_BUFFER && uniformInfo->location == bindingLocation) 3075 { 3076 const BufferUniform* bufferUniform = static_cast<const BufferUniform*>(uniformInfo); 3077 return bufferUniform->alloc->getHostPtr(); 3078 } 3079 } 3080 3081 return DE_NULL; 3082} 3083 3084void ShaderExecutor::addUniforms (const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc) 3085{ 3086 if (!m_uniformSetup) 3087 return; 3088 3089 for (std::vector<UniformDataSp>::const_iterator it = m_uniformSetup->uniforms().begin(); it != m_uniformSetup->uniforms().end(); ++it) 3090 { 3091 const UniformDataBase* uniformData = it->get()->get(); 3092 uniformData->setup(*this, vkDevice, vk, queue, queueFamilyIndex, memAlloc); 3093 } 3094} 3095 3096void ShaderExecutor::uploadUniforms (DescriptorSetUpdateBuilder& descriptorSetUpdateBuilder, VkDescriptorSet descriptorSet) 3097{ 3098 for (std::vector<UniformInfoSp>::const_iterator it = m_uniformInfos.begin(); it != m_uniformInfos.end(); ++it) 3099 { 3100 const UniformInfo* uniformInfo = it->get()->get(); 3101 UniformInfo::UniformType uniformType = uniformInfo->getType(); 3102 3103 if (uniformType == UniformInfo::UNIFORM_TYPE_BUFFER_ARRAY) 3104 { 3105 const BufferArrayUniform* arrayInfo = static_cast<const BufferArrayUniform*>(uniformInfo); 3106 std::vector<VkDescriptorBufferInfo> descriptors; 3107 3108 for (std::vector<BufferUniformSp>::const_iterator ait = arrayInfo->uniforms.begin(); ait != arrayInfo->uniforms.end(); ++ait) 3109 { 3110 descriptors.push_back(ait->get()->get()->descriptor); 3111 } 3112 3113 descriptorSetUpdateBuilder.writeArray(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(uniformInfo->location), uniformInfo->type, (deUint32)descriptors.size(), &descriptors[0]); 3114 } 3115 else if (uniformType == UniformInfo::UNIFORM_TYPE_SAMPLER_ARRAY) 3116 { 3117 const SamplerArrayUniform* arrayInfo = static_cast<const SamplerArrayUniform*>(uniformInfo); 3118 std::vector<VkDescriptorImageInfo> descriptors; 3119 3120 for (std::vector<SamplerUniformSp>::const_iterator ait = arrayInfo->uniforms.begin(); ait != arrayInfo->uniforms.end(); ++ait) 3121 { 3122 descriptors.push_back(ait->get()->get()->descriptor); 3123 } 3124 3125 descriptorSetUpdateBuilder.writeArray(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(uniformInfo->location), uniformInfo->type, (deUint32)descriptors.size(), &descriptors[0]); 3126 } 3127 else if (uniformType == UniformInfo::UNIFORM_TYPE_BUFFER) 3128 { 3129 const BufferUniform* bufferUniform = static_cast<const BufferUniform*>(uniformInfo); 3130 descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(bufferUniform->location), bufferUniform->type, &bufferUniform->descriptor); 3131 } 3132 else if (uniformType == UniformInfo::UNIFORM_TYPE_SAMPLER) 3133 { 3134 const SamplerUniform* samplerUniform = static_cast<const SamplerUniform*>(uniformInfo); 3135 descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(samplerUniform->location), samplerUniform->type, &samplerUniform->descriptor); 3136 } 3137 } 3138} 3139 3140void ShaderExecutor::uploadImage (const VkDevice& vkDevice, 3141 const DeviceInterface& vk, 3142 const VkQueue queue, 3143 const deUint32 queueFamilyIndex, 3144 Allocator& memAlloc, 3145 const tcu::TextureFormat& texFormat, 3146 const tcu::IVec3& texSize, 3147 const void* data, 3148 const deUint32 arraySize, 3149 const VkImageAspectFlags aspectMask, 3150 VkImage destImage) 3151{ 3152 deUint32 textureSize = texSize.x() * texSize.y() * texSize.z() * texFormat.getPixelSize(); 3153 deUint32 bufferSize; 3154 Move<VkBuffer> buffer; 3155 de::MovePtr<Allocation> bufferAlloc; 3156 Move<VkCommandPool> cmdPool; 3157 Move<VkCommandBuffer> cmdBuffer; 3158 Move<VkFence> fence; 3159 std::vector<deUint32> levelDataSizes; 3160 3161 // Calculate buffer size 3162 bufferSize = arraySize * textureSize; 3163 3164 // Create source buffer 3165 { 3166 const VkBufferCreateInfo bufferParams = 3167 { 3168 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 3169 DE_NULL, // const void* pNext; 3170 0u, // VkBufferCreateFlags flags; 3171 bufferSize, // VkDeviceSize size; 3172 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage; 3173 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 3174 0u, // deUint32 queueFamilyIndexCount; 3175 DE_NULL, // const deUint32* pQueueFamilyIndices; 3176 }; 3177 3178 buffer = createBuffer(vk, vkDevice, &bufferParams); 3179 bufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible); 3180 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 3181 } 3182 3183 // Create command pool and buffer 3184 { 3185 const VkCommandPoolCreateInfo cmdPoolParams = 3186 { 3187 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 3188 DE_NULL, // const void* pNext; 3189 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags; 3190 queueFamilyIndex, // deUint32 queueFamilyIndex; 3191 }; 3192 3193 cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams); 3194 3195 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = 3196 { 3197 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 3198 DE_NULL, // const void* pNext; 3199 *cmdPool, // VkCommandPool commandPool; 3200 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 3201 1u, // deUint32 bufferCount; 3202 }; 3203 3204 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo); 3205 } 3206 3207 // Create fence 3208 { 3209 const VkFenceCreateInfo fenceParams = 3210 { 3211 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 3212 DE_NULL, // const void* pNext; 3213 0u // VkFenceCreateFlags flags; 3214 }; 3215 3216 fence = createFence(vk, vkDevice, &fenceParams); 3217 } 3218 3219 // Barriers for copying buffer to image 3220 const VkBufferMemoryBarrier preBufferBarrier = 3221 { 3222 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 3223 DE_NULL, // const void* pNext; 3224 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask; 3225 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 3226 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 3227 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 3228 *buffer, // VkBuffer buffer; 3229 0u, // VkDeviceSize offset; 3230 bufferSize // VkDeviceSize size; 3231 }; 3232 3233 const VkImageMemoryBarrier preImageBarrier = 3234 { 3235 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 3236 DE_NULL, // const void* pNext; 3237 0u, // VkAccessFlags srcAccessMask; 3238 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 3239 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 3240 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; 3241 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 3242 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 3243 destImage, // VkImage image; 3244 { // VkImageSubresourceRange subresourceRange; 3245 aspectMask, // VkImageAspect aspect; 3246 0u, // deUint32 baseMipLevel; 3247 1u, // deUint32 mipLevels; 3248 0u, // deUint32 baseArraySlice; 3249 arraySize // deUint32 arraySize; 3250 } 3251 }; 3252 3253 const VkImageMemoryBarrier postImageBarrier = 3254 { 3255 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 3256 DE_NULL, // const void* pNext; 3257 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 3258 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask; 3259 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 3260 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout; 3261 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 3262 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 3263 destImage, // VkImage image; 3264 { // VkImageSubresourceRange subresourceRange; 3265 aspectMask, // VkImageAspect aspect; 3266 0u, // deUint32 baseMipLevel; 3267 1u, // deUint32 mipLevels; 3268 0u, // deUint32 baseArraySlice; 3269 arraySize // deUint32 arraySize; 3270 } 3271 }; 3272 3273 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 3274 { 3275 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 3276 DE_NULL, // const void* pNext; 3277 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 3278 (const VkCommandBufferInheritanceInfo*)DE_NULL, 3279 }; 3280 3281 std::vector<VkBufferImageCopy> copyRegions; 3282 3283 { 3284 deUint32 layerDataOffset = 0; 3285 3286 for (deUint32 layerNdx = 0; layerNdx < arraySize; ++layerNdx) 3287 { 3288 const VkBufferImageCopy layerRegion = 3289 { 3290 layerDataOffset, // VkDeviceSize bufferOffset; 3291 (deUint32)texSize.x(), // deUint32 bufferRowLength; 3292 (deUint32)texSize.y(), // deUint32 bufferImageHeight; 3293 { // VkImageSubresourceLayers imageSubresource; 3294 aspectMask, 3295 0u, 3296 (deUint32)layerNdx, 3297 1u 3298 }, 3299 { 0u, 0u, 0u }, // VkOffset3D imageOffset; 3300 { // VkExtent3D imageExtent; 3301 (deUint32)texSize.x(), 3302 (deUint32)texSize.y(), 3303 (deUint32)texSize.z() 3304 } 3305 }; 3306 3307 copyRegions.push_back(layerRegion); 3308 layerDataOffset += textureSize; 3309 } 3310 } 3311 3312 // Write buffer data 3313 { 3314 deUint8* destPtr = (deUint8*)bufferAlloc->getHostPtr(); 3315 deUint32 levelOffset = 0; 3316 3317 for (deUint32 layerNdx = 0; layerNdx < arraySize; ++layerNdx) 3318 { 3319 tcu::ConstPixelBufferAccess access (texFormat, texSize, data); 3320 tcu::PixelBufferAccess destAccess (texFormat, texSize, destPtr + levelOffset); 3321 3322 tcu::copy(destAccess, access); 3323 levelOffset += textureSize; 3324 } 3325 } 3326 3327 flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize); 3328 3329 // Copy buffer to image 3330 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); 3331 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier); 3332 vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data()); 3333 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier); 3334 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 3335 3336 const VkSubmitInfo submitInfo = 3337 { 3338 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 3339 DE_NULL, // const void* pNext; 3340 0u, // deUint32 waitSemaphoreCount; 3341 DE_NULL, // const VkSemaphore* pWaitSemaphores; 3342 DE_NULL, 3343 1u, // deUint32 commandBufferCount; 3344 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 3345 0u, // deUint32 signalSemaphoreCount; 3346 DE_NULL // const VkSemaphore* pSignalSemaphores; 3347 }; 3348 3349 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 3350 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */)); 3351} 3352 3353de::MovePtr<ShaderExecutor::SamplerUniform> ShaderExecutor::createSamplerUniform (const VkDevice& vkDevice, 3354 const DeviceInterface& vk, 3355 const VkQueue queue, 3356 const deUint32 queueFamilyIndex, 3357 Allocator& memAlloc, 3358 deUint32 bindingLocation, 3359 const tcu::Sampler& refSampler, 3360 const tcu::TextureFormat& texFormat, 3361 const tcu::IVec3& texSize, 3362 VkImageType imageType, 3363 VkImageViewType imageViewType, 3364 const void* data) 3365{ 3366 const VkFormat format = mapTextureFormat(texFormat); 3367 const bool isCube = imageViewType == VK_IMAGE_VIEW_TYPE_CUBE; 3368 const bool isShadowSampler = texFormat == tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16); 3369 const VkImageCreateFlags imageFlags = isCube ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlags)0; 3370 const deUint32 arraySize = isCube ? 6u : 1u; 3371 const VkImageAspectFlags aspectMask = isShadowSampler ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; 3372 VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 3373 Move<VkImage> vkTexture; 3374 de::MovePtr<Allocation> allocation; 3375 3376 if (isShadowSampler) 3377 imageUsage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; 3378 3379 // Create image 3380 const VkImageCreateInfo imageParams = 3381 { 3382 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 3383 DE_NULL, // const void* pNext; 3384 imageFlags, // VkImageCreateFlags flags; 3385 imageType, // VkImageType imageType; 3386 format, // VkFormat format; 3387 { // VkExtent3D extent; 3388 (deUint32)texSize.x(), 3389 (deUint32)texSize.y(), 3390 (deUint32)texSize.z() 3391 }, 3392 1u, // deUint32 mipLevels; 3393 arraySize, // deUint32 arrayLayers; 3394 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 3395 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 3396 imageUsage, // VkImageUsageFlags usage; 3397 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 3398 1u, // deUint32 queueFamilyIndexCount; 3399 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 3400 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 3401 }; 3402 3403 vkTexture = createImage(vk, vkDevice, &imageParams); 3404 allocation = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *vkTexture), MemoryRequirement::Any); 3405 VK_CHECK(vk.bindImageMemory(vkDevice, *vkTexture, allocation->getMemory(), allocation->getOffset())); 3406 3407 // Upload texture data 3408 uploadImage(vkDevice, vk, queue, queueFamilyIndex, memAlloc, texFormat, texSize, data, arraySize, aspectMask, *vkTexture); 3409 3410 // Create sampler 3411 const VkSamplerCreateInfo samplerParams = mapSampler(refSampler, texFormat); 3412 Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams); 3413 3414 const VkImageViewCreateInfo viewParams = 3415 { 3416 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 3417 NULL, // const voide* pNexŧ; 3418 0u, // VkImageViewCreateFlags flags; 3419 *vkTexture, // VkImage image; 3420 imageViewType, // VkImageViewType viewType; 3421 format, // VkFormat format; 3422 { 3423 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r; 3424 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g; 3425 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b; 3426 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a; 3427 }, // VkComponentMapping components; 3428 { 3429 aspectMask, // VkImageAspectFlags aspectMask; 3430 0, // deUint32 baseMipLevel; 3431 1, // deUint32 mipLevels; 3432 0, // deUint32 baseArraySlice; 3433 arraySize // deUint32 arraySize; 3434 } // VkImageSubresourceRange subresourceRange; 3435 }; 3436 3437 Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams); 3438 3439 const VkDescriptorImageInfo descriptor = 3440 { 3441 sampler.get(), // VkSampler sampler; 3442 imageView.get(), // VkImageView imageView; 3443 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout imageLayout; 3444 }; 3445 3446 de::MovePtr<SamplerUniform> uniform(new SamplerUniform()); 3447 uniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 3448 uniform->descriptor = descriptor; 3449 uniform->location = bindingLocation; 3450 uniform->image = VkImageSp(new Unique<VkImage>(vkTexture)); 3451 uniform->imageView = VkImageViewSp(new Unique<VkImageView>(imageView)); 3452 uniform->sampler = VkSamplerSp(new Unique<VkSampler>(sampler)); 3453 uniform->alloc = AllocationSp(allocation.release()); 3454 3455 return uniform; 3456} 3457 3458SamplerUniformData::SamplerUniformData (deUint32 bindingLocation, 3459 deUint32 numSamplers, 3460 const tcu::Sampler& refSampler, 3461 const tcu::TextureFormat& texFormat, 3462 const tcu::IVec3& texSize, 3463 VkImageType imageType, 3464 VkImageViewType imageViewType, 3465 const void* data) 3466 : UniformDataBase (bindingLocation) 3467 , m_numSamplers (numSamplers) 3468 , m_refSampler (refSampler) 3469 , m_texFormat (texFormat) 3470 , m_texSize (texSize) 3471 , m_imageType (imageType) 3472 , m_imageViewType (imageViewType) 3473 , m_data (data) 3474{ 3475} 3476 3477SamplerUniformData::~SamplerUniformData (void) 3478{ 3479} 3480 3481void SamplerUniformData::setup (ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc) const 3482{ 3483 executor.setupSamplerData(vkDevice, vk, queue, queueFamilyIndex, memAlloc, m_bindingLocation, m_numSamplers, m_refSampler, m_texFormat, m_texSize, m_imageType, m_imageViewType, m_data); 3484} 3485 3486} // shaderexecutor 3487} // vkt 3488