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