1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests 3e5c31af7Sopenharmony_ci * ------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2015 Google Inc. 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief ShaderLibrary Vulkan implementation 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "vktShaderLibrary.hpp" 25e5c31af7Sopenharmony_ci#include "vktTestCase.hpp" 26e5c31af7Sopenharmony_ci 27e5c31af7Sopenharmony_ci#include "vkPrograms.hpp" 28e5c31af7Sopenharmony_ci#include "vkRef.hpp" 29e5c31af7Sopenharmony_ci#include "vkRefUtil.hpp" 30e5c31af7Sopenharmony_ci#include "vkMemUtil.hpp" 31e5c31af7Sopenharmony_ci#include "vkQueryUtil.hpp" 32e5c31af7Sopenharmony_ci#include "vkBuilderUtil.hpp" 33e5c31af7Sopenharmony_ci#include "vkTypeUtil.hpp" 34e5c31af7Sopenharmony_ci#include "vkImageUtil.hpp" 35e5c31af7Sopenharmony_ci#include "vkCmdUtil.hpp" 36e5c31af7Sopenharmony_ci#include "vkObjUtil.hpp" 37e5c31af7Sopenharmony_ci 38e5c31af7Sopenharmony_ci#include "gluShaderLibrary.hpp" 39e5c31af7Sopenharmony_ci#include "gluShaderUtil.hpp" 40e5c31af7Sopenharmony_ci 41e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp" 42e5c31af7Sopenharmony_ci#include "tcuTexture.hpp" 43e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 44e5c31af7Sopenharmony_ci#include "tcuVector.hpp" 45e5c31af7Sopenharmony_ci#include "tcuVectorUtil.hpp" 46e5c31af7Sopenharmony_ci 47e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 48e5c31af7Sopenharmony_ci#include "deArrayUtil.hpp" 49e5c31af7Sopenharmony_ci#include "deMemory.h" 50e5c31af7Sopenharmony_ci 51e5c31af7Sopenharmony_ci#include <sstream> 52e5c31af7Sopenharmony_ci#include <map> 53e5c31af7Sopenharmony_ci 54e5c31af7Sopenharmony_cinamespace vkt 55e5c31af7Sopenharmony_ci{ 56e5c31af7Sopenharmony_ci 57e5c31af7Sopenharmony_ciusing std::string; 58e5c31af7Sopenharmony_ciusing std::vector; 59e5c31af7Sopenharmony_ciusing std::map; 60e5c31af7Sopenharmony_ciusing std::pair; 61e5c31af7Sopenharmony_ciusing std::ostringstream; 62e5c31af7Sopenharmony_ci 63e5c31af7Sopenharmony_ciusing de::MovePtr; 64e5c31af7Sopenharmony_ciusing de::UniquePtr; 65e5c31af7Sopenharmony_ci 66e5c31af7Sopenharmony_ciusing glu::ShaderType; 67e5c31af7Sopenharmony_ciusing glu::ProgramSources; 68e5c31af7Sopenharmony_ciusing glu::DataType; 69e5c31af7Sopenharmony_ci 70e5c31af7Sopenharmony_ciusing glu::sl::ShaderCaseSpecification; 71e5c31af7Sopenharmony_ciusing glu::sl::ProgramSpecializationParams; 72e5c31af7Sopenharmony_ciusing glu::sl::RequiredExtension; 73e5c31af7Sopenharmony_ciusing glu::sl::Value; 74e5c31af7Sopenharmony_ciusing glu::sl::ValueBlock; 75e5c31af7Sopenharmony_ci 76e5c31af7Sopenharmony_ciusing tcu::TestStatus; 77e5c31af7Sopenharmony_ciusing tcu::StringTemplate; 78e5c31af7Sopenharmony_ciusing tcu::Vec2; 79e5c31af7Sopenharmony_ciusing tcu::ConstPixelBufferAccess; 80e5c31af7Sopenharmony_ciusing tcu::TextureFormat; 81e5c31af7Sopenharmony_ciusing tcu::TestLog; 82e5c31af7Sopenharmony_ci 83e5c31af7Sopenharmony_ciusing vk::SourceCollections; 84e5c31af7Sopenharmony_ciusing vk::Move; 85e5c31af7Sopenharmony_ciusing vk::Unique; 86e5c31af7Sopenharmony_ci 87e5c31af7Sopenharmony_cinamespace 88e5c31af7Sopenharmony_ci{ 89e5c31af7Sopenharmony_ci 90e5c31af7Sopenharmony_cienum 91e5c31af7Sopenharmony_ci{ 92e5c31af7Sopenharmony_ci REFERENCE_UNIFORM_BINDING = 0, 93e5c31af7Sopenharmony_ci USER_UNIFORM_BINDING = 1 94e5c31af7Sopenharmony_ci}; 95e5c31af7Sopenharmony_ci 96e5c31af7Sopenharmony_cistring getShaderName (ShaderType shaderType, size_t progNdx) 97e5c31af7Sopenharmony_ci{ 98e5c31af7Sopenharmony_ci ostringstream str; 99e5c31af7Sopenharmony_ci str << glu::getShaderTypeName(shaderType); 100e5c31af7Sopenharmony_ci if (progNdx > 0) 101e5c31af7Sopenharmony_ci str << "_" << progNdx; 102e5c31af7Sopenharmony_ci return str.str(); 103e5c31af7Sopenharmony_ci} 104e5c31af7Sopenharmony_ci 105e5c31af7Sopenharmony_civoid genUniformBlock (ostringstream& out, const string& blockName, const string& instanceName, int setNdx, int bindingNdx, const vector<Value>& uniforms) 106e5c31af7Sopenharmony_ci{ 107e5c31af7Sopenharmony_ci out << "layout("; 108e5c31af7Sopenharmony_ci 109e5c31af7Sopenharmony_ci if (setNdx != 0) 110e5c31af7Sopenharmony_ci out << "set = " << setNdx << ", "; 111e5c31af7Sopenharmony_ci 112e5c31af7Sopenharmony_ci out << "binding = " << bindingNdx << ", std140) uniform " << blockName << "\n" 113e5c31af7Sopenharmony_ci << "{\n"; 114e5c31af7Sopenharmony_ci 115e5c31af7Sopenharmony_ci for (vector<Value>::const_iterator val = uniforms.begin(); val != uniforms.end(); ++val) 116e5c31af7Sopenharmony_ci out << "\t" << glu::declare(val->type, val->name, 1) << ";\n"; 117e5c31af7Sopenharmony_ci 118e5c31af7Sopenharmony_ci out << "}"; 119e5c31af7Sopenharmony_ci 120e5c31af7Sopenharmony_ci if (!instanceName.empty()) 121e5c31af7Sopenharmony_ci out << " " << instanceName; 122e5c31af7Sopenharmony_ci 123e5c31af7Sopenharmony_ci out << ";\n"; 124e5c31af7Sopenharmony_ci} 125e5c31af7Sopenharmony_ci 126e5c31af7Sopenharmony_civoid declareReferenceBlock (ostringstream& out, const ValueBlock& valueBlock) 127e5c31af7Sopenharmony_ci{ 128e5c31af7Sopenharmony_ci if (!valueBlock.outputs.empty()) 129e5c31af7Sopenharmony_ci genUniformBlock(out, "Reference", "ref", 0, REFERENCE_UNIFORM_BINDING, valueBlock.outputs); 130e5c31af7Sopenharmony_ci} 131e5c31af7Sopenharmony_ci 132e5c31af7Sopenharmony_civoid declareUniforms (ostringstream& out, const ValueBlock& valueBlock) 133e5c31af7Sopenharmony_ci{ 134e5c31af7Sopenharmony_ci if (!valueBlock.uniforms.empty()) 135e5c31af7Sopenharmony_ci genUniformBlock(out, "Uniforms", "", 0, USER_UNIFORM_BINDING, valueBlock.uniforms); 136e5c31af7Sopenharmony_ci} 137e5c31af7Sopenharmony_ci 138e5c31af7Sopenharmony_ciDataType getTransportType (DataType valueType) 139e5c31af7Sopenharmony_ci{ 140e5c31af7Sopenharmony_ci if (isDataTypeBoolOrBVec(valueType)) 141e5c31af7Sopenharmony_ci return glu::getDataTypeUintVec(getDataTypeScalarSize(valueType)); 142e5c31af7Sopenharmony_ci else 143e5c31af7Sopenharmony_ci return valueType; 144e5c31af7Sopenharmony_ci} 145e5c31af7Sopenharmony_ci 146e5c31af7Sopenharmony_ciint getNumTransportLocations (DataType valueType) 147e5c31af7Sopenharmony_ci{ 148e5c31af7Sopenharmony_ci return isDataTypeMatrix(valueType) ? getDataTypeMatrixNumColumns(valueType) : 1; 149e5c31af7Sopenharmony_ci} 150e5c31af7Sopenharmony_ci 151e5c31af7Sopenharmony_ci// This functions builds a matching vertex shader for a 'both' case, when 152e5c31af7Sopenharmony_ci// the fragment shader is being tested. 153e5c31af7Sopenharmony_ci// We need to build attributes and varyings for each 'input'. 154e5c31af7Sopenharmony_cistring genVertexShader (const ShaderCaseSpecification& spec) 155e5c31af7Sopenharmony_ci{ 156e5c31af7Sopenharmony_ci ostringstream res; 157e5c31af7Sopenharmony_ci int curInputLoc = 0; 158e5c31af7Sopenharmony_ci int curOutputLoc = 0; 159e5c31af7Sopenharmony_ci 160e5c31af7Sopenharmony_ci res << glu::getGLSLVersionDeclaration(spec.targetVersion) << "\n"; 161e5c31af7Sopenharmony_ci 162e5c31af7Sopenharmony_ci // Declarations (position + attribute/varying for each input). 163e5c31af7Sopenharmony_ci res << "precision highp float;\n"; 164e5c31af7Sopenharmony_ci res << "precision highp int;\n"; 165e5c31af7Sopenharmony_ci res << "\n"; 166e5c31af7Sopenharmony_ci res << "layout(location = 0) in highp vec4 dEQP_Position;\n"; 167e5c31af7Sopenharmony_ci curInputLoc += 1; 168e5c31af7Sopenharmony_ci 169e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < spec.values.inputs.size(); ndx++) 170e5c31af7Sopenharmony_ci { 171e5c31af7Sopenharmony_ci const Value& val = spec.values.inputs[ndx]; 172e5c31af7Sopenharmony_ci const DataType valueType = val.type.getBasicType(); 173e5c31af7Sopenharmony_ci const DataType transportType = getTransportType(valueType); 174e5c31af7Sopenharmony_ci const char* const transportTypeStr = getDataTypeName(transportType); 175e5c31af7Sopenharmony_ci const int numLocs = getNumTransportLocations(valueType); 176e5c31af7Sopenharmony_ci 177e5c31af7Sopenharmony_ci res << "layout(location = " << curInputLoc << ") in " << transportTypeStr << " a_" << val.name << ";\n"; 178e5c31af7Sopenharmony_ci res << "layout(location = " << curOutputLoc << ") flat out " << transportTypeStr << " " << (transportType != valueType ? "v_" : "") << val.name << ";\n"; 179e5c31af7Sopenharmony_ci 180e5c31af7Sopenharmony_ci curInputLoc += numLocs; 181e5c31af7Sopenharmony_ci curOutputLoc += numLocs; 182e5c31af7Sopenharmony_ci } 183e5c31af7Sopenharmony_ci res << "\n"; 184e5c31af7Sopenharmony_ci 185e5c31af7Sopenharmony_ci // Main function. 186e5c31af7Sopenharmony_ci // - gl_Position = dEQP_Position; 187e5c31af7Sopenharmony_ci // - for each input: write attribute directly to varying 188e5c31af7Sopenharmony_ci res << "void main()\n"; 189e5c31af7Sopenharmony_ci res << "{\n"; 190e5c31af7Sopenharmony_ci res << " gl_Position = dEQP_Position;\n"; 191e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < spec.values.inputs.size(); ndx++) 192e5c31af7Sopenharmony_ci { 193e5c31af7Sopenharmony_ci const Value& val = spec.values.inputs[ndx]; 194e5c31af7Sopenharmony_ci const string& name = val.name; 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_ci res << " " << (getTransportType(val.type.getBasicType()) != val.type.getBasicType() ? "v_" : "") 197e5c31af7Sopenharmony_ci << name << " = a_" << name << ";\n"; 198e5c31af7Sopenharmony_ci } 199e5c31af7Sopenharmony_ci 200e5c31af7Sopenharmony_ci res << "}\n"; 201e5c31af7Sopenharmony_ci return res.str(); 202e5c31af7Sopenharmony_ci} 203e5c31af7Sopenharmony_ci 204e5c31af7Sopenharmony_civoid genCompareOp (ostringstream& output, const char* dstVec4Var, const ValueBlock& valueBlock, const char* checkVarName) 205e5c31af7Sopenharmony_ci{ 206e5c31af7Sopenharmony_ci bool isFirstOutput = true; 207e5c31af7Sopenharmony_ci 208e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < valueBlock.outputs.size(); ndx++) 209e5c31af7Sopenharmony_ci { 210e5c31af7Sopenharmony_ci const Value& val = valueBlock.outputs[ndx]; 211e5c31af7Sopenharmony_ci 212e5c31af7Sopenharmony_ci // Check if we're only interested in one variable (then skip if not the right one). 213e5c31af7Sopenharmony_ci if (checkVarName && val.name != checkVarName) 214e5c31af7Sopenharmony_ci continue; 215e5c31af7Sopenharmony_ci 216e5c31af7Sopenharmony_ci // Prefix. 217e5c31af7Sopenharmony_ci if (isFirstOutput) 218e5c31af7Sopenharmony_ci { 219e5c31af7Sopenharmony_ci output << "bool RES = "; 220e5c31af7Sopenharmony_ci isFirstOutput = false; 221e5c31af7Sopenharmony_ci } 222e5c31af7Sopenharmony_ci else 223e5c31af7Sopenharmony_ci output << "RES = RES && "; 224e5c31af7Sopenharmony_ci 225e5c31af7Sopenharmony_ci // Generate actual comparison. 226e5c31af7Sopenharmony_ci if (getDataTypeScalarType(val.type.getBasicType()) == glu::TYPE_FLOAT) 227e5c31af7Sopenharmony_ci output << "isOk(" << val.name << ", ref." << val.name << ", 0.05);\n"; 228e5c31af7Sopenharmony_ci else 229e5c31af7Sopenharmony_ci output << "isOk(" << val.name << ", ref." << val.name << ");\n"; 230e5c31af7Sopenharmony_ci } 231e5c31af7Sopenharmony_ci 232e5c31af7Sopenharmony_ci if (isFirstOutput) 233e5c31af7Sopenharmony_ci output << dstVec4Var << " = vec4(1.0);\n"; 234e5c31af7Sopenharmony_ci else 235e5c31af7Sopenharmony_ci output << dstVec4Var << " = vec4(RES, RES, RES, 1.0);\n"; 236e5c31af7Sopenharmony_ci} 237e5c31af7Sopenharmony_ci 238e5c31af7Sopenharmony_cistring genFragmentShader (const ShaderCaseSpecification& spec) 239e5c31af7Sopenharmony_ci{ 240e5c31af7Sopenharmony_ci ostringstream shader; 241e5c31af7Sopenharmony_ci ostringstream setup; 242e5c31af7Sopenharmony_ci int curInLoc = 0; 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_ci shader << glu::getGLSLVersionDeclaration(spec.targetVersion) << "\n"; 245e5c31af7Sopenharmony_ci 246e5c31af7Sopenharmony_ci shader << "precision highp float;\n"; 247e5c31af7Sopenharmony_ci shader << "precision highp int;\n"; 248e5c31af7Sopenharmony_ci shader << "\n"; 249e5c31af7Sopenharmony_ci 250e5c31af7Sopenharmony_ci shader << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"; 251e5c31af7Sopenharmony_ci shader << "\n"; 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_ci genCompareFunctions(shader, spec.values, false); 254e5c31af7Sopenharmony_ci shader << "\n"; 255e5c31af7Sopenharmony_ci 256e5c31af7Sopenharmony_ci // Declarations (varying, reference for each output). 257e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < spec.values.outputs.size(); ndx++) 258e5c31af7Sopenharmony_ci { 259e5c31af7Sopenharmony_ci const Value& val = spec.values.outputs[ndx]; 260e5c31af7Sopenharmony_ci const DataType valueType = val.type.getBasicType(); 261e5c31af7Sopenharmony_ci const char* const valueTypeStr = getDataTypeName(valueType); 262e5c31af7Sopenharmony_ci const DataType transportType = getTransportType(valueType); 263e5c31af7Sopenharmony_ci const char* const transportTypeStr = getDataTypeName(transportType); 264e5c31af7Sopenharmony_ci const int numLocs = getNumTransportLocations(valueType); 265e5c31af7Sopenharmony_ci 266e5c31af7Sopenharmony_ci shader << "layout(location = " << curInLoc << ") flat in " << transportTypeStr << " " << (valueType != transportType ? "v_" : "") << val.name << ";\n"; 267e5c31af7Sopenharmony_ci 268e5c31af7Sopenharmony_ci if (valueType != transportType) 269e5c31af7Sopenharmony_ci setup << " " << valueTypeStr << " " << val.name << " = " << valueTypeStr << "(v_" << val.name << ");\n"; 270e5c31af7Sopenharmony_ci 271e5c31af7Sopenharmony_ci curInLoc += numLocs; 272e5c31af7Sopenharmony_ci } 273e5c31af7Sopenharmony_ci 274e5c31af7Sopenharmony_ci declareReferenceBlock(shader, spec.values); 275e5c31af7Sopenharmony_ci 276e5c31af7Sopenharmony_ci shader << "\n"; 277e5c31af7Sopenharmony_ci shader << "void main()\n"; 278e5c31af7Sopenharmony_ci shader << "{\n"; 279e5c31af7Sopenharmony_ci 280e5c31af7Sopenharmony_ci shader << setup.str(); 281e5c31af7Sopenharmony_ci 282e5c31af7Sopenharmony_ci shader << " "; 283e5c31af7Sopenharmony_ci genCompareOp(shader, "dEQP_FragColor", spec.values, DE_NULL); 284e5c31af7Sopenharmony_ci 285e5c31af7Sopenharmony_ci shader << "}\n"; 286e5c31af7Sopenharmony_ci return shader.str(); 287e5c31af7Sopenharmony_ci} 288e5c31af7Sopenharmony_ci 289e5c31af7Sopenharmony_ci// Specialize a shader for the vertex shader test case. 290e5c31af7Sopenharmony_cistring specializeVertexShader (const ShaderCaseSpecification& spec, const string& src) 291e5c31af7Sopenharmony_ci{ 292e5c31af7Sopenharmony_ci ostringstream decl; 293e5c31af7Sopenharmony_ci ostringstream setup; 294e5c31af7Sopenharmony_ci ostringstream output; 295e5c31af7Sopenharmony_ci int curInputLoc = 0; 296e5c31af7Sopenharmony_ci int curOutputLoc = 0; 297e5c31af7Sopenharmony_ci 298e5c31af7Sopenharmony_ci // generated from "both" case 299e5c31af7Sopenharmony_ci DE_ASSERT(spec.caseType == glu::sl::CASETYPE_VERTEX_ONLY); 300e5c31af7Sopenharmony_ci 301e5c31af7Sopenharmony_ci // Output (write out position). 302e5c31af7Sopenharmony_ci output << "gl_Position = dEQP_Position;\n"; 303e5c31af7Sopenharmony_ci 304e5c31af7Sopenharmony_ci // Declarations (position + attribute for each input, varying for each output). 305e5c31af7Sopenharmony_ci decl << "layout(location = 0) in highp vec4 dEQP_Position;\n"; 306e5c31af7Sopenharmony_ci curInputLoc += 1; 307e5c31af7Sopenharmony_ci 308e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < spec.values.inputs.size(); ndx++) 309e5c31af7Sopenharmony_ci { 310e5c31af7Sopenharmony_ci const Value& val = spec.values.inputs[ndx]; 311e5c31af7Sopenharmony_ci const DataType valueType = val.type.getBasicType(); 312e5c31af7Sopenharmony_ci const char* const valueTypeStr = getDataTypeName(valueType); 313e5c31af7Sopenharmony_ci const DataType transportType = getTransportType(valueType); 314e5c31af7Sopenharmony_ci const char* const transportTypeStr = getDataTypeName(transportType); 315e5c31af7Sopenharmony_ci const int numLocs = getNumTransportLocations(valueType); 316e5c31af7Sopenharmony_ci 317e5c31af7Sopenharmony_ci decl << "layout(location = " << curInputLoc << ") in "; 318e5c31af7Sopenharmony_ci 319e5c31af7Sopenharmony_ci curInputLoc += numLocs; 320e5c31af7Sopenharmony_ci 321e5c31af7Sopenharmony_ci if (valueType == transportType) 322e5c31af7Sopenharmony_ci decl << transportTypeStr << " " << val.name << ";\n"; 323e5c31af7Sopenharmony_ci else 324e5c31af7Sopenharmony_ci { 325e5c31af7Sopenharmony_ci decl << transportTypeStr << " a_" << val.name << ";\n"; 326e5c31af7Sopenharmony_ci setup << valueTypeStr << " " << val.name << " = " << valueTypeStr << "(a_" << val.name << ");\n"; 327e5c31af7Sopenharmony_ci } 328e5c31af7Sopenharmony_ci } 329e5c31af7Sopenharmony_ci 330e5c31af7Sopenharmony_ci declareUniforms(decl, spec.values); 331e5c31af7Sopenharmony_ci 332e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < spec.values.outputs.size(); ndx++) 333e5c31af7Sopenharmony_ci { 334e5c31af7Sopenharmony_ci const Value& val = spec.values.outputs[ndx]; 335e5c31af7Sopenharmony_ci const DataType valueType = val.type.getBasicType(); 336e5c31af7Sopenharmony_ci const char* const valueTypeStr = getDataTypeName(valueType); 337e5c31af7Sopenharmony_ci const DataType transportType = getTransportType(valueType); 338e5c31af7Sopenharmony_ci const char* const transportTypeStr = getDataTypeName(transportType); 339e5c31af7Sopenharmony_ci const int numLocs = getNumTransportLocations(valueType); 340e5c31af7Sopenharmony_ci 341e5c31af7Sopenharmony_ci decl << "layout(location = " << curOutputLoc << ") flat out "; 342e5c31af7Sopenharmony_ci 343e5c31af7Sopenharmony_ci curOutputLoc += numLocs; 344e5c31af7Sopenharmony_ci 345e5c31af7Sopenharmony_ci if (valueType == transportType) 346e5c31af7Sopenharmony_ci decl << transportTypeStr << " " << val.name << ";\n"; 347e5c31af7Sopenharmony_ci else 348e5c31af7Sopenharmony_ci { 349e5c31af7Sopenharmony_ci decl << transportTypeStr << " v_" << val.name << ";\n"; 350e5c31af7Sopenharmony_ci decl << valueTypeStr << " " << val.name << ";\n"; 351e5c31af7Sopenharmony_ci 352e5c31af7Sopenharmony_ci output << "v_" << val.name << " = " << transportTypeStr << "(" << val.name << ");\n"; 353e5c31af7Sopenharmony_ci } 354e5c31af7Sopenharmony_ci } 355e5c31af7Sopenharmony_ci 356e5c31af7Sopenharmony_ci // Shader specialization. 357e5c31af7Sopenharmony_ci map<string, string> params; 358e5c31af7Sopenharmony_ci params.insert(pair<string, string>("DECLARATIONS", decl.str())); 359e5c31af7Sopenharmony_ci params.insert(pair<string, string>("SETUP", setup.str())); 360e5c31af7Sopenharmony_ci params.insert(pair<string, string>("OUTPUT", output.str())); 361e5c31af7Sopenharmony_ci params.insert(pair<string, string>("POSITION_FRAG_COLOR", "gl_Position")); 362e5c31af7Sopenharmony_ci 363e5c31af7Sopenharmony_ci StringTemplate tmpl (src); 364e5c31af7Sopenharmony_ci const string baseSrc = tmpl.specialize(params); 365e5c31af7Sopenharmony_ci const string withExt = injectExtensionRequirements(baseSrc, spec.programs[0].requiredExtensions, glu::SHADERTYPE_VERTEX); 366e5c31af7Sopenharmony_ci 367e5c31af7Sopenharmony_ci return withExt; 368e5c31af7Sopenharmony_ci} 369e5c31af7Sopenharmony_ci 370e5c31af7Sopenharmony_ci// Specialize a shader for the fragment shader test case. 371e5c31af7Sopenharmony_cistring specializeFragmentShader (const ShaderCaseSpecification& spec, const string& src) 372e5c31af7Sopenharmony_ci{ 373e5c31af7Sopenharmony_ci ostringstream decl; 374e5c31af7Sopenharmony_ci ostringstream setup; 375e5c31af7Sopenharmony_ci ostringstream output; 376e5c31af7Sopenharmony_ci int curInputLoc = 0; 377e5c31af7Sopenharmony_ci 378e5c31af7Sopenharmony_ci // generated from "both" case 379e5c31af7Sopenharmony_ci DE_ASSERT(spec.caseType == glu::sl::CASETYPE_FRAGMENT_ONLY); 380e5c31af7Sopenharmony_ci 381e5c31af7Sopenharmony_ci genCompareFunctions(decl, spec.values, false); 382e5c31af7Sopenharmony_ci genCompareOp(output, "dEQP_FragColor", spec.values, DE_NULL); 383e5c31af7Sopenharmony_ci 384e5c31af7Sopenharmony_ci decl << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"; 385e5c31af7Sopenharmony_ci 386e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < spec.values.inputs.size(); ndx++) 387e5c31af7Sopenharmony_ci { 388e5c31af7Sopenharmony_ci const Value& val = spec.values.inputs[ndx]; 389e5c31af7Sopenharmony_ci const DataType valueType = val.type.getBasicType(); 390e5c31af7Sopenharmony_ci const char* const valueTypeStr = getDataTypeName(valueType); 391e5c31af7Sopenharmony_ci const DataType transportType = getTransportType(valueType); 392e5c31af7Sopenharmony_ci const char* const transportTypeStr = getDataTypeName(transportType); 393e5c31af7Sopenharmony_ci const int numLocs = getNumTransportLocations(valueType); 394e5c31af7Sopenharmony_ci 395e5c31af7Sopenharmony_ci decl << "layout(location = " << curInputLoc << ") flat in "; 396e5c31af7Sopenharmony_ci 397e5c31af7Sopenharmony_ci curInputLoc += numLocs; 398e5c31af7Sopenharmony_ci 399e5c31af7Sopenharmony_ci if (valueType == transportType) 400e5c31af7Sopenharmony_ci decl << transportTypeStr << " " << val.name << ";\n"; 401e5c31af7Sopenharmony_ci else 402e5c31af7Sopenharmony_ci { 403e5c31af7Sopenharmony_ci decl << transportTypeStr << " v_" << val.name << ";\n"; 404e5c31af7Sopenharmony_ci setup << valueTypeStr << " " << val.name << " = " << valueTypeStr << "(v_" << val.name << ");\n"; 405e5c31af7Sopenharmony_ci } 406e5c31af7Sopenharmony_ci } 407e5c31af7Sopenharmony_ci 408e5c31af7Sopenharmony_ci declareUniforms(decl, spec.values); 409e5c31af7Sopenharmony_ci declareReferenceBlock(decl, spec.values); 410e5c31af7Sopenharmony_ci 411e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < spec.values.outputs.size(); ndx++) 412e5c31af7Sopenharmony_ci { 413e5c31af7Sopenharmony_ci const Value& val = spec.values.outputs[ndx]; 414e5c31af7Sopenharmony_ci const DataType basicType = val.type.getBasicType(); 415e5c31af7Sopenharmony_ci const char* const refTypeStr = getDataTypeName(basicType); 416e5c31af7Sopenharmony_ci 417e5c31af7Sopenharmony_ci decl << refTypeStr << " " << val.name << ";\n"; 418e5c31af7Sopenharmony_ci } 419e5c31af7Sopenharmony_ci 420e5c31af7Sopenharmony_ci // Shader specialization. 421e5c31af7Sopenharmony_ci map<string, string> params; 422e5c31af7Sopenharmony_ci params.insert(pair<string, string>("DECLARATIONS", decl.str())); 423e5c31af7Sopenharmony_ci params.insert(pair<string, string>("SETUP", setup.str())); 424e5c31af7Sopenharmony_ci params.insert(pair<string, string>("OUTPUT", output.str())); 425e5c31af7Sopenharmony_ci params.insert(pair<string, string>("POSITION_FRAG_COLOR", "dEQP_FragColor")); 426e5c31af7Sopenharmony_ci 427e5c31af7Sopenharmony_ci StringTemplate tmpl (src); 428e5c31af7Sopenharmony_ci const string baseSrc = tmpl.specialize(params); 429e5c31af7Sopenharmony_ci const string withExt = injectExtensionRequirements(baseSrc, spec.programs[0].requiredExtensions, glu::SHADERTYPE_FRAGMENT); 430e5c31af7Sopenharmony_ci 431e5c31af7Sopenharmony_ci return withExt; 432e5c31af7Sopenharmony_ci} 433e5c31af7Sopenharmony_ci 434e5c31af7Sopenharmony_cimap<string, string> generateVertexSpecialization (const ProgramSpecializationParams& specParams) 435e5c31af7Sopenharmony_ci{ 436e5c31af7Sopenharmony_ci ostringstream decl; 437e5c31af7Sopenharmony_ci ostringstream setup; 438e5c31af7Sopenharmony_ci map<string, string> params; 439e5c31af7Sopenharmony_ci int curInputLoc = 0; 440e5c31af7Sopenharmony_ci 441e5c31af7Sopenharmony_ci decl << "layout(location = 0) in highp vec4 dEQP_Position;\n"; 442e5c31af7Sopenharmony_ci curInputLoc += 1; 443e5c31af7Sopenharmony_ci 444e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < specParams.caseSpec.values.inputs.size(); ndx++) 445e5c31af7Sopenharmony_ci { 446e5c31af7Sopenharmony_ci const Value& val = specParams.caseSpec.values.inputs[ndx]; 447e5c31af7Sopenharmony_ci const DataType valueType = val.type.getBasicType(); 448e5c31af7Sopenharmony_ci const char* const valueTypeStr = getDataTypeName(valueType); 449e5c31af7Sopenharmony_ci const DataType transportType = getTransportType(valueType); 450e5c31af7Sopenharmony_ci const char* const transportTypeStr = getDataTypeName(transportType); 451e5c31af7Sopenharmony_ci const int numLocs = getNumTransportLocations(valueType); 452e5c31af7Sopenharmony_ci 453e5c31af7Sopenharmony_ci decl << "layout(location = " << curInputLoc << ") in "; 454e5c31af7Sopenharmony_ci 455e5c31af7Sopenharmony_ci curInputLoc += numLocs; 456e5c31af7Sopenharmony_ci 457e5c31af7Sopenharmony_ci if (valueType == transportType) 458e5c31af7Sopenharmony_ci decl << transportTypeStr << " " << val.name << ";\n"; 459e5c31af7Sopenharmony_ci else 460e5c31af7Sopenharmony_ci { 461e5c31af7Sopenharmony_ci decl << transportTypeStr << " a_" << val.name << ";\n"; 462e5c31af7Sopenharmony_ci setup << valueTypeStr << " " << val.name << " = " << valueTypeStr << "(a_" << val.name << ");\n"; 463e5c31af7Sopenharmony_ci } 464e5c31af7Sopenharmony_ci } 465e5c31af7Sopenharmony_ci 466e5c31af7Sopenharmony_ci declareUniforms(decl, specParams.caseSpec.values); 467e5c31af7Sopenharmony_ci 468e5c31af7Sopenharmony_ci params.insert(pair<string, string>("VERTEX_DECLARATIONS", decl.str())); 469e5c31af7Sopenharmony_ci params.insert(pair<string, string>("VERTEX_SETUP", setup.str())); 470e5c31af7Sopenharmony_ci params.insert(pair<string, string>("VERTEX_OUTPUT", string("gl_Position = dEQP_Position;\n"))); 471e5c31af7Sopenharmony_ci 472e5c31af7Sopenharmony_ci return params; 473e5c31af7Sopenharmony_ci} 474e5c31af7Sopenharmony_ci 475e5c31af7Sopenharmony_cimap<string, string> generateFragmentSpecialization (const ProgramSpecializationParams& specParams) 476e5c31af7Sopenharmony_ci{ 477e5c31af7Sopenharmony_ci ostringstream decl; 478e5c31af7Sopenharmony_ci ostringstream output; 479e5c31af7Sopenharmony_ci map<string, string> params; 480e5c31af7Sopenharmony_ci 481e5c31af7Sopenharmony_ci genCompareFunctions(decl, specParams.caseSpec.values, false); 482e5c31af7Sopenharmony_ci genCompareOp(output, "dEQP_FragColor", specParams.caseSpec.values, DE_NULL); 483e5c31af7Sopenharmony_ci 484e5c31af7Sopenharmony_ci decl << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"; 485e5c31af7Sopenharmony_ci 486e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < specParams.caseSpec.values.outputs.size(); ndx++) 487e5c31af7Sopenharmony_ci { 488e5c31af7Sopenharmony_ci const Value& val = specParams.caseSpec.values.outputs[ndx]; 489e5c31af7Sopenharmony_ci const char* const refTypeStr = getDataTypeName(val.type.getBasicType()); 490e5c31af7Sopenharmony_ci 491e5c31af7Sopenharmony_ci decl << refTypeStr << " " << val.name << ";\n"; 492e5c31af7Sopenharmony_ci } 493e5c31af7Sopenharmony_ci 494e5c31af7Sopenharmony_ci declareReferenceBlock(decl, specParams.caseSpec.values); 495e5c31af7Sopenharmony_ci declareUniforms(decl, specParams.caseSpec.values); 496e5c31af7Sopenharmony_ci 497e5c31af7Sopenharmony_ci params.insert(pair<string, string>("FRAGMENT_DECLARATIONS", decl.str())); 498e5c31af7Sopenharmony_ci params.insert(pair<string, string>("FRAGMENT_OUTPUT", output.str())); 499e5c31af7Sopenharmony_ci params.insert(pair<string, string>("FRAG_COLOR", "dEQP_FragColor")); 500e5c31af7Sopenharmony_ci 501e5c31af7Sopenharmony_ci return params; 502e5c31af7Sopenharmony_ci} 503e5c31af7Sopenharmony_ci 504e5c31af7Sopenharmony_cimap<string, string> generateGeometrySpecialization (const ProgramSpecializationParams& specParams) 505e5c31af7Sopenharmony_ci{ 506e5c31af7Sopenharmony_ci ostringstream decl; 507e5c31af7Sopenharmony_ci map<string, string> params; 508e5c31af7Sopenharmony_ci 509e5c31af7Sopenharmony_ci decl << "layout (triangles) in;\n"; 510e5c31af7Sopenharmony_ci decl << "layout (triangle_strip, max_vertices=3) out;\n"; 511e5c31af7Sopenharmony_ci decl << "\n"; 512e5c31af7Sopenharmony_ci 513e5c31af7Sopenharmony_ci declareUniforms(decl, specParams.caseSpec.values); 514e5c31af7Sopenharmony_ci 515e5c31af7Sopenharmony_ci params.insert(pair<string, string>("GEOMETRY_DECLARATIONS", decl.str())); 516e5c31af7Sopenharmony_ci 517e5c31af7Sopenharmony_ci return params; 518e5c31af7Sopenharmony_ci} 519e5c31af7Sopenharmony_ci 520e5c31af7Sopenharmony_cimap<string, string> generateTessControlSpecialization (const ProgramSpecializationParams& specParams) 521e5c31af7Sopenharmony_ci{ 522e5c31af7Sopenharmony_ci ostringstream decl; 523e5c31af7Sopenharmony_ci ostringstream output; 524e5c31af7Sopenharmony_ci map<string, string> params; 525e5c31af7Sopenharmony_ci 526e5c31af7Sopenharmony_ci decl << "layout (vertices=3) out;\n"; 527e5c31af7Sopenharmony_ci decl << "\n"; 528e5c31af7Sopenharmony_ci 529e5c31af7Sopenharmony_ci declareUniforms(decl, specParams.caseSpec.values); 530e5c31af7Sopenharmony_ci 531e5c31af7Sopenharmony_ci output << "gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 532e5c31af7Sopenharmony_ci "gl_TessLevelInner[0] = 2.0;\n" 533e5c31af7Sopenharmony_ci "gl_TessLevelInner[1] = 2.0;\n" 534e5c31af7Sopenharmony_ci "gl_TessLevelOuter[0] = 2.0;\n" 535e5c31af7Sopenharmony_ci "gl_TessLevelOuter[1] = 2.0;\n" 536e5c31af7Sopenharmony_ci "gl_TessLevelOuter[2] = 2.0;\n" 537e5c31af7Sopenharmony_ci "gl_TessLevelOuter[3] = 2.0;"; 538e5c31af7Sopenharmony_ci 539e5c31af7Sopenharmony_ci params.insert(pair<string, string>("TESSELLATION_CONTROL_DECLARATIONS", decl.str())); 540e5c31af7Sopenharmony_ci params.insert(pair<string, string>("TESSELLATION_CONTROL_OUTPUT", output.str())); 541e5c31af7Sopenharmony_ci params.insert(pair<string, string>("GL_MAX_PATCH_VERTICES", de::toString(specParams.maxPatchVertices))); 542e5c31af7Sopenharmony_ci 543e5c31af7Sopenharmony_ci return params; 544e5c31af7Sopenharmony_ci} 545e5c31af7Sopenharmony_ci 546e5c31af7Sopenharmony_cimap<string, string> generateTessEvalSpecialization (const ProgramSpecializationParams& specParams) 547e5c31af7Sopenharmony_ci{ 548e5c31af7Sopenharmony_ci ostringstream decl; 549e5c31af7Sopenharmony_ci ostringstream output; 550e5c31af7Sopenharmony_ci map<string, string> params; 551e5c31af7Sopenharmony_ci 552e5c31af7Sopenharmony_ci decl << "layout (triangles) in;\n"; 553e5c31af7Sopenharmony_ci decl << "\n"; 554e5c31af7Sopenharmony_ci 555e5c31af7Sopenharmony_ci declareUniforms(decl, specParams.caseSpec.values); 556e5c31af7Sopenharmony_ci 557e5c31af7Sopenharmony_ci output << "gl_Position = gl_TessCoord[0] * gl_in[0].gl_Position + gl_TessCoord[1] * gl_in[1].gl_Position + gl_TessCoord[2] * gl_in[2].gl_Position;\n"; 558e5c31af7Sopenharmony_ci 559e5c31af7Sopenharmony_ci params.insert(pair<string, string>("TESSELLATION_EVALUATION_DECLARATIONS", decl.str())); 560e5c31af7Sopenharmony_ci params.insert(pair<string, string>("TESSELLATION_EVALUATION_OUTPUT", output.str())); 561e5c31af7Sopenharmony_ci params.insert(pair<string, string>("GL_MAX_PATCH_VERTICES", de::toString(specParams.maxPatchVertices))); 562e5c31af7Sopenharmony_ci 563e5c31af7Sopenharmony_ci return params; 564e5c31af7Sopenharmony_ci} 565e5c31af7Sopenharmony_ci 566e5c31af7Sopenharmony_civoid specializeShaderSources (ProgramSources& dst, 567e5c31af7Sopenharmony_ci const ProgramSources& src, 568e5c31af7Sopenharmony_ci const ProgramSpecializationParams& specParams, 569e5c31af7Sopenharmony_ci glu::ShaderType shaderType, 570e5c31af7Sopenharmony_ci map<string, string> (*specializationGenerator) (const ProgramSpecializationParams& specParams)) 571e5c31af7Sopenharmony_ci{ 572e5c31af7Sopenharmony_ci if (!src.sources[shaderType].empty()) 573e5c31af7Sopenharmony_ci { 574e5c31af7Sopenharmony_ci const map<string, string> tmplParams = specializationGenerator(specParams); 575e5c31af7Sopenharmony_ci 576e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < src.sources[shaderType].size(); ++ndx) 577e5c31af7Sopenharmony_ci { 578e5c31af7Sopenharmony_ci const StringTemplate tmpl (src.sources[shaderType][ndx]); 579e5c31af7Sopenharmony_ci const string baseGLSLCode = tmpl.specialize(tmplParams); 580e5c31af7Sopenharmony_ci const string sourceWithExts = injectExtensionRequirements(baseGLSLCode, specParams.requiredExtensions, shaderType); 581e5c31af7Sopenharmony_ci 582e5c31af7Sopenharmony_ci dst << glu::ShaderSource(shaderType, sourceWithExts); 583e5c31af7Sopenharmony_ci } 584e5c31af7Sopenharmony_ci } 585e5c31af7Sopenharmony_ci} 586e5c31af7Sopenharmony_ci 587e5c31af7Sopenharmony_civoid specializeProgramSources (glu::ProgramSources& dst, 588e5c31af7Sopenharmony_ci const glu::ProgramSources& src, 589e5c31af7Sopenharmony_ci const ProgramSpecializationParams& specParams) 590e5c31af7Sopenharmony_ci{ 591e5c31af7Sopenharmony_ci specializeShaderSources(dst, src, specParams, glu::SHADERTYPE_VERTEX, generateVertexSpecialization); 592e5c31af7Sopenharmony_ci specializeShaderSources(dst, src, specParams, glu::SHADERTYPE_FRAGMENT, generateFragmentSpecialization); 593e5c31af7Sopenharmony_ci specializeShaderSources(dst, src, specParams, glu::SHADERTYPE_GEOMETRY, generateGeometrySpecialization); 594e5c31af7Sopenharmony_ci specializeShaderSources(dst, src, specParams, glu::SHADERTYPE_TESSELLATION_CONTROL, generateTessControlSpecialization); 595e5c31af7Sopenharmony_ci specializeShaderSources(dst, src, specParams, glu::SHADERTYPE_TESSELLATION_EVALUATION, generateTessEvalSpecialization); 596e5c31af7Sopenharmony_ci 597e5c31af7Sopenharmony_ci dst << glu::ProgramSeparable(src.separable); 598e5c31af7Sopenharmony_ci} 599e5c31af7Sopenharmony_ci 600e5c31af7Sopenharmony_cistruct ValueBufferLayout 601e5c31af7Sopenharmony_ci{ 602e5c31af7Sopenharmony_ci struct Entry 603e5c31af7Sopenharmony_ci { 604e5c31af7Sopenharmony_ci int offset; 605e5c31af7Sopenharmony_ci int vecStride; //! Applies to matrices only 606e5c31af7Sopenharmony_ci 607e5c31af7Sopenharmony_ci Entry (void) : offset(0), vecStride(0) {} 608e5c31af7Sopenharmony_ci Entry (int offset_, int vecStride_) : offset(offset_), vecStride(vecStride_) {} 609e5c31af7Sopenharmony_ci }; 610e5c31af7Sopenharmony_ci 611e5c31af7Sopenharmony_ci vector<Entry> entries; 612e5c31af7Sopenharmony_ci int size; 613e5c31af7Sopenharmony_ci 614e5c31af7Sopenharmony_ci ValueBufferLayout (void) : size(0) {} 615e5c31af7Sopenharmony_ci}; 616e5c31af7Sopenharmony_ci 617e5c31af7Sopenharmony_ciValueBufferLayout computeStd140Layout (const vector<Value>& values) 618e5c31af7Sopenharmony_ci{ 619e5c31af7Sopenharmony_ci ValueBufferLayout layout; 620e5c31af7Sopenharmony_ci 621e5c31af7Sopenharmony_ci layout.entries.resize(values.size()); 622e5c31af7Sopenharmony_ci 623e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < values.size(); ++ndx) 624e5c31af7Sopenharmony_ci { 625e5c31af7Sopenharmony_ci const DataType basicType = values[ndx].type.getBasicType(); 626e5c31af7Sopenharmony_ci const bool isMatrix = isDataTypeMatrix(basicType); 627e5c31af7Sopenharmony_ci const int numVecs = isMatrix ? getDataTypeMatrixNumColumns(basicType) : 1; 628e5c31af7Sopenharmony_ci const DataType vecType = isMatrix ? glu::getDataTypeFloatVec(getDataTypeMatrixNumRows(basicType)) : basicType; 629e5c31af7Sopenharmony_ci const int vecSize = getDataTypeScalarSize(vecType); 630e5c31af7Sopenharmony_ci const int alignment = ((isMatrix || vecSize == 3) ? 4 : vecSize)*int(sizeof(deUint32)); 631e5c31af7Sopenharmony_ci 632e5c31af7Sopenharmony_ci layout.size = deAlign32(layout.size, alignment); 633e5c31af7Sopenharmony_ci layout.entries[ndx] = ValueBufferLayout::Entry(layout.size, alignment); 634e5c31af7Sopenharmony_ci layout.size += alignment*(numVecs-1) + vecSize*int(sizeof(deUint32)); 635e5c31af7Sopenharmony_ci } 636e5c31af7Sopenharmony_ci 637e5c31af7Sopenharmony_ci return layout; 638e5c31af7Sopenharmony_ci} 639e5c31af7Sopenharmony_ci 640e5c31af7Sopenharmony_ciValueBufferLayout computeStd430Layout (const vector<Value>& values) 641e5c31af7Sopenharmony_ci{ 642e5c31af7Sopenharmony_ci ValueBufferLayout layout; 643e5c31af7Sopenharmony_ci 644e5c31af7Sopenharmony_ci layout.entries.resize(values.size()); 645e5c31af7Sopenharmony_ci 646e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < values.size(); ++ndx) 647e5c31af7Sopenharmony_ci { 648e5c31af7Sopenharmony_ci const DataType basicType = values[ndx].type.getBasicType(); 649e5c31af7Sopenharmony_ci const int numVecs = isDataTypeMatrix(basicType) ? getDataTypeMatrixNumColumns(basicType) : 1; 650e5c31af7Sopenharmony_ci const DataType vecType = isDataTypeMatrix(basicType) ? glu::getDataTypeFloatVec(getDataTypeMatrixNumRows(basicType)) : basicType; 651e5c31af7Sopenharmony_ci const int vecSize = getDataTypeScalarSize(vecType); 652e5c31af7Sopenharmony_ci const int alignment = (vecSize == 3 ? 4 : vecSize)*int(sizeof(deUint32)); 653e5c31af7Sopenharmony_ci 654e5c31af7Sopenharmony_ci layout.size = deAlign32(layout.size, alignment); 655e5c31af7Sopenharmony_ci layout.entries[ndx] = ValueBufferLayout::Entry(layout.size, alignment); 656e5c31af7Sopenharmony_ci layout.size += alignment*(numVecs-1) + vecSize*int(sizeof(deUint32)); 657e5c31af7Sopenharmony_ci } 658e5c31af7Sopenharmony_ci 659e5c31af7Sopenharmony_ci return layout; 660e5c31af7Sopenharmony_ci} 661e5c31af7Sopenharmony_ci 662e5c31af7Sopenharmony_civoid copyToLayout (void* dst, const ValueBufferLayout::Entry& entryLayout, const Value& value, int arrayNdx) 663e5c31af7Sopenharmony_ci{ 664e5c31af7Sopenharmony_ci const DataType basicType = value.type.getBasicType(); 665e5c31af7Sopenharmony_ci const int scalarSize = getDataTypeScalarSize(basicType); 666e5c31af7Sopenharmony_ci const int numVecs = isDataTypeMatrix(basicType) ? getDataTypeMatrixNumColumns(basicType) : 1; 667e5c31af7Sopenharmony_ci const int numComps = isDataTypeMatrix(basicType) ? getDataTypeMatrixNumRows(basicType) : scalarSize; 668e5c31af7Sopenharmony_ci 669e5c31af7Sopenharmony_ci DE_ASSERT(size_t((arrayNdx+1)*scalarSize) <= value.elements.size()); 670e5c31af7Sopenharmony_ci 671e5c31af7Sopenharmony_ci if (isDataTypeBoolOrBVec(basicType)) 672e5c31af7Sopenharmony_ci { 673e5c31af7Sopenharmony_ci for (int vecNdx = 0; vecNdx < numVecs; vecNdx++) 674e5c31af7Sopenharmony_ci { 675e5c31af7Sopenharmony_ci for (int compNdx = 0; compNdx < numComps; compNdx++) 676e5c31af7Sopenharmony_ci { 677e5c31af7Sopenharmony_ci const deUint32 data = value.elements[arrayNdx*scalarSize + vecNdx*numComps + compNdx].bool32 ? ~0u : 0u; 678e5c31af7Sopenharmony_ci 679e5c31af7Sopenharmony_ci deMemcpy((deUint8*)dst + entryLayout.offset + vecNdx*entryLayout.vecStride + compNdx * sizeof(deUint32), 680e5c31af7Sopenharmony_ci &data, 681e5c31af7Sopenharmony_ci sizeof(deUint32)); 682e5c31af7Sopenharmony_ci } 683e5c31af7Sopenharmony_ci } 684e5c31af7Sopenharmony_ci } 685e5c31af7Sopenharmony_ci else 686e5c31af7Sopenharmony_ci { 687e5c31af7Sopenharmony_ci for (int vecNdx = 0; vecNdx < numVecs; vecNdx++) 688e5c31af7Sopenharmony_ci deMemcpy((deUint8*)dst + entryLayout.offset + vecNdx*entryLayout.vecStride, 689e5c31af7Sopenharmony_ci &value.elements[arrayNdx*scalarSize + vecNdx*numComps], 690e5c31af7Sopenharmony_ci numComps*sizeof(deUint32)); 691e5c31af7Sopenharmony_ci } 692e5c31af7Sopenharmony_ci} 693e5c31af7Sopenharmony_ci 694e5c31af7Sopenharmony_civoid copyToLayout (void* dst, const ValueBufferLayout& layout, const vector<Value>& values, int arrayNdx) 695e5c31af7Sopenharmony_ci{ 696e5c31af7Sopenharmony_ci DE_ASSERT(layout.entries.size() == values.size()); 697e5c31af7Sopenharmony_ci 698e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < values.size(); ndx++) 699e5c31af7Sopenharmony_ci copyToLayout(dst, layout.entries[ndx], values[ndx], arrayNdx); 700e5c31af7Sopenharmony_ci} 701e5c31af7Sopenharmony_ci 702e5c31af7Sopenharmony_cideUint32 getShaderStages (const ShaderCaseSpecification& spec) 703e5c31af7Sopenharmony_ci{ 704e5c31af7Sopenharmony_ci if (spec.caseType == glu::sl::CASETYPE_COMPLETE) 705e5c31af7Sopenharmony_ci { 706e5c31af7Sopenharmony_ci deUint32 stages = 0u; 707e5c31af7Sopenharmony_ci 708e5c31af7Sopenharmony_ci for (size_t progNdx = 0; progNdx < spec.programs.size(); progNdx++) 709e5c31af7Sopenharmony_ci { 710e5c31af7Sopenharmony_ci for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; shaderType++) 711e5c31af7Sopenharmony_ci { 712e5c31af7Sopenharmony_ci if (!spec.programs[progNdx].sources.sources[shaderType].empty()) 713e5c31af7Sopenharmony_ci stages |= (1u << shaderType); 714e5c31af7Sopenharmony_ci } 715e5c31af7Sopenharmony_ci } 716e5c31af7Sopenharmony_ci 717e5c31af7Sopenharmony_ci return stages; 718e5c31af7Sopenharmony_ci } 719e5c31af7Sopenharmony_ci else 720e5c31af7Sopenharmony_ci return (1u << glu::SHADERTYPE_VERTEX) | (1u << glu::SHADERTYPE_FRAGMENT); 721e5c31af7Sopenharmony_ci} 722e5c31af7Sopenharmony_ci 723e5c31af7Sopenharmony_ciclass PipelineProgram 724e5c31af7Sopenharmony_ci{ 725e5c31af7Sopenharmony_cipublic: 726e5c31af7Sopenharmony_ci PipelineProgram (Context& context, const ShaderCaseSpecification& spec); 727e5c31af7Sopenharmony_ci 728e5c31af7Sopenharmony_ci deUint32 getStages (void) const { return m_stages; } 729e5c31af7Sopenharmony_ci 730e5c31af7Sopenharmony_ci bool hasShader (glu::ShaderType type) const { return (m_stages & (1u << type)) != 0; } 731e5c31af7Sopenharmony_ci vk::VkShaderModule getShader (glu::ShaderType type) const { return *m_shaderModules[type]; } 732e5c31af7Sopenharmony_ci 733e5c31af7Sopenharmony_ciprivate: 734e5c31af7Sopenharmony_ci const deUint32 m_stages; 735e5c31af7Sopenharmony_ci Move<vk::VkShaderModule> m_shaderModules[glu::SHADERTYPE_LAST]; 736e5c31af7Sopenharmony_ci}; 737e5c31af7Sopenharmony_ci 738e5c31af7Sopenharmony_ciPipelineProgram::PipelineProgram (Context& context, const ShaderCaseSpecification& spec) 739e5c31af7Sopenharmony_ci : m_stages(getShaderStages(spec)) 740e5c31af7Sopenharmony_ci{ 741e5c31af7Sopenharmony_ci // \note Currently only a single source program is supported as framework lacks SPIR-V linking capability 742e5c31af7Sopenharmony_ci TCU_CHECK_INTERNAL(spec.programs.size() == 1); 743e5c31af7Sopenharmony_ci 744e5c31af7Sopenharmony_ci for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; shaderType++) 745e5c31af7Sopenharmony_ci { 746e5c31af7Sopenharmony_ci if ((m_stages & (1u << shaderType)) != 0) 747e5c31af7Sopenharmony_ci { 748e5c31af7Sopenharmony_ci m_shaderModules[shaderType] = vk::createShaderModule(context.getDeviceInterface(), context.getDevice(), 749e5c31af7Sopenharmony_ci context.getBinaryCollection().get(getShaderName((glu::ShaderType)shaderType, 0)), 0u); 750e5c31af7Sopenharmony_ci } 751e5c31af7Sopenharmony_ci } 752e5c31af7Sopenharmony_ci} 753e5c31af7Sopenharmony_ci 754e5c31af7Sopenharmony_ciMove<vk::VkBuffer> createBuffer (Context& context, vk::VkDeviceSize size, vk::VkBufferUsageFlags usageFlags) 755e5c31af7Sopenharmony_ci{ 756e5c31af7Sopenharmony_ci const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 757e5c31af7Sopenharmony_ci const vk::VkBufferCreateInfo params = 758e5c31af7Sopenharmony_ci { 759e5c31af7Sopenharmony_ci vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType 760e5c31af7Sopenharmony_ci DE_NULL, // pNext 761e5c31af7Sopenharmony_ci 0u, // flags 762e5c31af7Sopenharmony_ci size, // size 763e5c31af7Sopenharmony_ci usageFlags, // usage 764e5c31af7Sopenharmony_ci vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode 765e5c31af7Sopenharmony_ci 1u, // queueFamilyCount 766e5c31af7Sopenharmony_ci &queueFamilyIndex, // pQueueFamilyIndices 767e5c31af7Sopenharmony_ci }; 768e5c31af7Sopenharmony_ci 769e5c31af7Sopenharmony_ci return vk::createBuffer(context.getDeviceInterface(), context.getDevice(), ¶ms); 770e5c31af7Sopenharmony_ci} 771e5c31af7Sopenharmony_ci 772e5c31af7Sopenharmony_ciMove<vk::VkImage> createImage2D (Context& context, deUint32 width, deUint32 height, vk::VkFormat format, vk::VkImageTiling tiling, vk::VkImageUsageFlags usageFlags) 773e5c31af7Sopenharmony_ci{ 774e5c31af7Sopenharmony_ci const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 775e5c31af7Sopenharmony_ci const vk::VkImageCreateInfo params = 776e5c31af7Sopenharmony_ci { 777e5c31af7Sopenharmony_ci vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType 778e5c31af7Sopenharmony_ci DE_NULL, // pNext 779e5c31af7Sopenharmony_ci 0u, // flags 780e5c31af7Sopenharmony_ci vk::VK_IMAGE_TYPE_2D, // imageType 781e5c31af7Sopenharmony_ci format, // format 782e5c31af7Sopenharmony_ci { width, height, 1u }, // extent 783e5c31af7Sopenharmony_ci 1u, // mipLevels 784e5c31af7Sopenharmony_ci 1u, // arraySize 785e5c31af7Sopenharmony_ci vk::VK_SAMPLE_COUNT_1_BIT, // samples 786e5c31af7Sopenharmony_ci tiling, // tiling 787e5c31af7Sopenharmony_ci usageFlags, // usage 788e5c31af7Sopenharmony_ci vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode 789e5c31af7Sopenharmony_ci 1u, // queueFamilyCount 790e5c31af7Sopenharmony_ci &queueFamilyIndex, // pQueueFamilyIndices 791e5c31af7Sopenharmony_ci vk::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout 792e5c31af7Sopenharmony_ci }; 793e5c31af7Sopenharmony_ci 794e5c31af7Sopenharmony_ci return vk::createImage(context.getDeviceInterface(), context.getDevice(), ¶ms); 795e5c31af7Sopenharmony_ci} 796e5c31af7Sopenharmony_ci 797e5c31af7Sopenharmony_ciMove<vk::VkImageView> createAttachmentView (Context& context, vk::VkImage image, vk::VkFormat format) 798e5c31af7Sopenharmony_ci{ 799e5c31af7Sopenharmony_ci const vk::VkImageViewCreateInfo params = 800e5c31af7Sopenharmony_ci { 801e5c31af7Sopenharmony_ci vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // sType 802e5c31af7Sopenharmony_ci DE_NULL, // pNext 803e5c31af7Sopenharmony_ci 0u, // flags 804e5c31af7Sopenharmony_ci image, // image 805e5c31af7Sopenharmony_ci vk::VK_IMAGE_VIEW_TYPE_2D, // viewType 806e5c31af7Sopenharmony_ci format, // format 807e5c31af7Sopenharmony_ci vk::makeComponentMappingRGBA(), // channels 808e5c31af7Sopenharmony_ci { 809e5c31af7Sopenharmony_ci vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask 810e5c31af7Sopenharmony_ci 0u, // baseMipLevel 811e5c31af7Sopenharmony_ci 1u, // mipLevels 812e5c31af7Sopenharmony_ci 0u, // baseArrayLayer 813e5c31af7Sopenharmony_ci 1u, // arraySize 814e5c31af7Sopenharmony_ci }, // subresourceRange 815e5c31af7Sopenharmony_ci }; 816e5c31af7Sopenharmony_ci 817e5c31af7Sopenharmony_ci return vk::createImageView(context.getDeviceInterface(), context.getDevice(), ¶ms); 818e5c31af7Sopenharmony_ci} 819e5c31af7Sopenharmony_ci 820e5c31af7Sopenharmony_ciMove<vk::VkRenderPass> createRenderPass (Context& context, vk::VkFormat colorAttFormat, deUint32 size) 821e5c31af7Sopenharmony_ci{ 822e5c31af7Sopenharmony_ci vk::VkAttachmentDescription colorAttDesc[4]; 823e5c31af7Sopenharmony_ci vk::VkAttachmentReference colorAttRef[4]; 824e5c31af7Sopenharmony_ci 825e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < size; i++) 826e5c31af7Sopenharmony_ci { 827e5c31af7Sopenharmony_ci vk::VkAttachmentDescription desc = 828e5c31af7Sopenharmony_ci { 829e5c31af7Sopenharmony_ci 0u, // flags 830e5c31af7Sopenharmony_ci colorAttFormat, // format 831e5c31af7Sopenharmony_ci vk::VK_SAMPLE_COUNT_1_BIT, // samples 832e5c31af7Sopenharmony_ci vk::VK_ATTACHMENT_LOAD_OP_CLEAR, // loadOp 833e5c31af7Sopenharmony_ci vk::VK_ATTACHMENT_STORE_OP_STORE, // storeOp 834e5c31af7Sopenharmony_ci vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp 835e5c31af7Sopenharmony_ci vk::VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp 836e5c31af7Sopenharmony_ci vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // initialLayout 837e5c31af7Sopenharmony_ci vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // finalLayout 838e5c31af7Sopenharmony_ci }; 839e5c31af7Sopenharmony_ci colorAttDesc[i] = desc; 840e5c31af7Sopenharmony_ci 841e5c31af7Sopenharmony_ci vk::VkAttachmentReference ref = 842e5c31af7Sopenharmony_ci { 843e5c31af7Sopenharmony_ci i, // attachment 844e5c31af7Sopenharmony_ci vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // layout 845e5c31af7Sopenharmony_ci }; 846e5c31af7Sopenharmony_ci colorAttRef[i] = ref; 847e5c31af7Sopenharmony_ci } 848e5c31af7Sopenharmony_ci 849e5c31af7Sopenharmony_ci const vk::VkAttachmentReference dsAttRef = 850e5c31af7Sopenharmony_ci { 851e5c31af7Sopenharmony_ci VK_ATTACHMENT_UNUSED, // attachment 852e5c31af7Sopenharmony_ci vk::VK_IMAGE_LAYOUT_GENERAL, // layout 853e5c31af7Sopenharmony_ci }; 854e5c31af7Sopenharmony_ci const vk::VkSubpassDescription subpassDesc = 855e5c31af7Sopenharmony_ci { 856e5c31af7Sopenharmony_ci (vk::VkSubpassDescriptionFlags)0, 857e5c31af7Sopenharmony_ci vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint 858e5c31af7Sopenharmony_ci 0u, // inputCount 859e5c31af7Sopenharmony_ci DE_NULL, // pInputAttachments 860e5c31af7Sopenharmony_ci size, // colorCount 861e5c31af7Sopenharmony_ci &colorAttRef[0], // pColorAttachments 862e5c31af7Sopenharmony_ci DE_NULL, // pResolveAttachments 863e5c31af7Sopenharmony_ci &dsAttRef, // depthStencilAttachment 864e5c31af7Sopenharmony_ci 0u, // preserveCount 865e5c31af7Sopenharmony_ci DE_NULL, // pPreserveAttachments 866e5c31af7Sopenharmony_ci 867e5c31af7Sopenharmony_ci }; 868e5c31af7Sopenharmony_ci const vk::VkRenderPassCreateInfo renderPassParams = 869e5c31af7Sopenharmony_ci { 870e5c31af7Sopenharmony_ci vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // sType 871e5c31af7Sopenharmony_ci DE_NULL, // pNext 872e5c31af7Sopenharmony_ci (vk::VkRenderPassCreateFlags)0, 873e5c31af7Sopenharmony_ci size, // attachmentCount 874e5c31af7Sopenharmony_ci &colorAttDesc[0], // pAttachments 875e5c31af7Sopenharmony_ci 1u, // subpassCount 876e5c31af7Sopenharmony_ci &subpassDesc, // pSubpasses 877e5c31af7Sopenharmony_ci 0u, // dependencyCount 878e5c31af7Sopenharmony_ci DE_NULL, // pDependencies 879e5c31af7Sopenharmony_ci }; 880e5c31af7Sopenharmony_ci 881e5c31af7Sopenharmony_ci return vk::createRenderPass(context.getDeviceInterface(), context.getDevice(), &renderPassParams); 882e5c31af7Sopenharmony_ci} 883e5c31af7Sopenharmony_ci 884e5c31af7Sopenharmony_civk::VkShaderStageFlags getVkStageFlags (deUint32 stages) 885e5c31af7Sopenharmony_ci{ 886e5c31af7Sopenharmony_ci vk::VkShaderStageFlags vkStages = 0u; 887e5c31af7Sopenharmony_ci 888e5c31af7Sopenharmony_ci for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; shaderType++) 889e5c31af7Sopenharmony_ci { 890e5c31af7Sopenharmony_ci if ((stages & (1u << shaderType)) != 0) 891e5c31af7Sopenharmony_ci vkStages |= vk::getVkShaderStage((glu::ShaderType)shaderType); 892e5c31af7Sopenharmony_ci } 893e5c31af7Sopenharmony_ci 894e5c31af7Sopenharmony_ci return vkStages; 895e5c31af7Sopenharmony_ci} 896e5c31af7Sopenharmony_ci 897e5c31af7Sopenharmony_ciMove<vk::VkDescriptorSetLayout> createDescriptorSetLayout (Context& context, deUint32 shaderStages) 898e5c31af7Sopenharmony_ci{ 899e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(REFERENCE_UNIFORM_BINDING == 0); 900e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(USER_UNIFORM_BINDING == 1); 901e5c31af7Sopenharmony_ci 902e5c31af7Sopenharmony_ci return vk::DescriptorSetLayoutBuilder() 903e5c31af7Sopenharmony_ci .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, vk::VK_SHADER_STAGE_FRAGMENT_BIT) 904e5c31af7Sopenharmony_ci .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, getVkStageFlags(shaderStages)) 905e5c31af7Sopenharmony_ci .build(context.getDeviceInterface(), context.getDevice()); 906e5c31af7Sopenharmony_ci} 907e5c31af7Sopenharmony_ci 908e5c31af7Sopenharmony_ciMove<vk::VkPipelineLayout> createPipelineLayout (Context& context, vk::VkDescriptorSetLayout descriptorSetLayout) 909e5c31af7Sopenharmony_ci{ 910e5c31af7Sopenharmony_ci const vk::VkPipelineLayoutCreateInfo params = 911e5c31af7Sopenharmony_ci { 912e5c31af7Sopenharmony_ci vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType 913e5c31af7Sopenharmony_ci DE_NULL, // pNext 914e5c31af7Sopenharmony_ci (vk::VkPipelineLayoutCreateFlags)0, 915e5c31af7Sopenharmony_ci 1u, // descriptorSetCount 916e5c31af7Sopenharmony_ci &descriptorSetLayout, // pSetLayouts 917e5c31af7Sopenharmony_ci 0u, // pushConstantRangeCount 918e5c31af7Sopenharmony_ci DE_NULL, // pPushConstantRanges 919e5c31af7Sopenharmony_ci }; 920e5c31af7Sopenharmony_ci 921e5c31af7Sopenharmony_ci return vk::createPipelineLayout(context.getDeviceInterface(), context.getDevice(), ¶ms); 922e5c31af7Sopenharmony_ci} 923e5c31af7Sopenharmony_ci 924e5c31af7Sopenharmony_civk::VkFormat getVecFormat (DataType scalarType, int scalarSize) 925e5c31af7Sopenharmony_ci{ 926e5c31af7Sopenharmony_ci switch (scalarType) 927e5c31af7Sopenharmony_ci { 928e5c31af7Sopenharmony_ci case glu::TYPE_FLOAT: 929e5c31af7Sopenharmony_ci { 930e5c31af7Sopenharmony_ci const vk::VkFormat vecFmts[] = 931e5c31af7Sopenharmony_ci { 932e5c31af7Sopenharmony_ci vk::VK_FORMAT_R32_SFLOAT, 933e5c31af7Sopenharmony_ci vk::VK_FORMAT_R32G32_SFLOAT, 934e5c31af7Sopenharmony_ci vk::VK_FORMAT_R32G32B32_SFLOAT, 935e5c31af7Sopenharmony_ci vk::VK_FORMAT_R32G32B32A32_SFLOAT, 936e5c31af7Sopenharmony_ci }; 937e5c31af7Sopenharmony_ci return de::getSizedArrayElement<4>(vecFmts, scalarSize-1); 938e5c31af7Sopenharmony_ci } 939e5c31af7Sopenharmony_ci 940e5c31af7Sopenharmony_ci case glu::TYPE_INT: 941e5c31af7Sopenharmony_ci { 942e5c31af7Sopenharmony_ci const vk::VkFormat vecFmts[] = 943e5c31af7Sopenharmony_ci { 944e5c31af7Sopenharmony_ci vk::VK_FORMAT_R32_SINT, 945e5c31af7Sopenharmony_ci vk::VK_FORMAT_R32G32_SINT, 946e5c31af7Sopenharmony_ci vk::VK_FORMAT_R32G32B32_SINT, 947e5c31af7Sopenharmony_ci vk::VK_FORMAT_R32G32B32A32_SINT, 948e5c31af7Sopenharmony_ci }; 949e5c31af7Sopenharmony_ci return de::getSizedArrayElement<4>(vecFmts, scalarSize-1); 950e5c31af7Sopenharmony_ci } 951e5c31af7Sopenharmony_ci 952e5c31af7Sopenharmony_ci case glu::TYPE_UINT: 953e5c31af7Sopenharmony_ci { 954e5c31af7Sopenharmony_ci const vk::VkFormat vecFmts[] = 955e5c31af7Sopenharmony_ci { 956e5c31af7Sopenharmony_ci vk::VK_FORMAT_R32_UINT, 957e5c31af7Sopenharmony_ci vk::VK_FORMAT_R32G32_UINT, 958e5c31af7Sopenharmony_ci vk::VK_FORMAT_R32G32B32_UINT, 959e5c31af7Sopenharmony_ci vk::VK_FORMAT_R32G32B32A32_UINT, 960e5c31af7Sopenharmony_ci }; 961e5c31af7Sopenharmony_ci return de::getSizedArrayElement<4>(vecFmts, scalarSize-1); 962e5c31af7Sopenharmony_ci } 963e5c31af7Sopenharmony_ci 964e5c31af7Sopenharmony_ci case glu::TYPE_BOOL: 965e5c31af7Sopenharmony_ci { 966e5c31af7Sopenharmony_ci const vk::VkFormat vecFmts[] = 967e5c31af7Sopenharmony_ci { 968e5c31af7Sopenharmony_ci vk::VK_FORMAT_R32_UINT, 969e5c31af7Sopenharmony_ci vk::VK_FORMAT_R32G32_UINT, 970e5c31af7Sopenharmony_ci vk::VK_FORMAT_R32G32B32_UINT, 971e5c31af7Sopenharmony_ci vk::VK_FORMAT_R32G32B32A32_UINT, 972e5c31af7Sopenharmony_ci }; 973e5c31af7Sopenharmony_ci return de::getSizedArrayElement<4>(vecFmts, scalarSize-1); 974e5c31af7Sopenharmony_ci } 975e5c31af7Sopenharmony_ci 976e5c31af7Sopenharmony_ci default: 977e5c31af7Sopenharmony_ci DE_FATAL("Unknown scalar type"); 978e5c31af7Sopenharmony_ci return vk::VK_FORMAT_R8G8B8A8_UINT; 979e5c31af7Sopenharmony_ci } 980e5c31af7Sopenharmony_ci} 981e5c31af7Sopenharmony_ci 982e5c31af7Sopenharmony_civector<vk::VkVertexInputAttributeDescription> getVertexAttributeDescriptions (const vector<Value>& inputValues, const ValueBufferLayout& layout) 983e5c31af7Sopenharmony_ci{ 984e5c31af7Sopenharmony_ci vector<vk::VkVertexInputAttributeDescription> attribs; 985e5c31af7Sopenharmony_ci 986e5c31af7Sopenharmony_ci // Position 987e5c31af7Sopenharmony_ci { 988e5c31af7Sopenharmony_ci const vk::VkVertexInputAttributeDescription posDesc = 989e5c31af7Sopenharmony_ci { 990e5c31af7Sopenharmony_ci 0u, // location 991e5c31af7Sopenharmony_ci 0u, // binding 992e5c31af7Sopenharmony_ci vk::VK_FORMAT_R32G32_SFLOAT, // format 993e5c31af7Sopenharmony_ci 0u, // offset 994e5c31af7Sopenharmony_ci }; 995e5c31af7Sopenharmony_ci 996e5c31af7Sopenharmony_ci attribs.push_back(posDesc); 997e5c31af7Sopenharmony_ci } 998e5c31af7Sopenharmony_ci 999e5c31af7Sopenharmony_ci // Input values 1000e5c31af7Sopenharmony_ci for (size_t inputNdx = 0; inputNdx < inputValues.size(); inputNdx++) 1001e5c31af7Sopenharmony_ci { 1002e5c31af7Sopenharmony_ci const Value& input = inputValues[inputNdx]; 1003e5c31af7Sopenharmony_ci const ValueBufferLayout::Entry& layoutEntry = layout.entries[inputNdx]; 1004e5c31af7Sopenharmony_ci const DataType basicType = input.type.getBasicType(); 1005e5c31af7Sopenharmony_ci const int numVecs = isDataTypeMatrix(basicType) 1006e5c31af7Sopenharmony_ci ? getDataTypeMatrixNumColumns(basicType) 1007e5c31af7Sopenharmony_ci : 1; 1008e5c31af7Sopenharmony_ci const int vecSize = isDataTypeMatrix(basicType) 1009e5c31af7Sopenharmony_ci ? getDataTypeMatrixNumRows(basicType) 1010e5c31af7Sopenharmony_ci : getDataTypeScalarSize(basicType); 1011e5c31af7Sopenharmony_ci const DataType scalarType = getDataTypeScalarType(basicType); 1012e5c31af7Sopenharmony_ci const vk::VkFormat vecFmt = getVecFormat(scalarType, vecSize); 1013e5c31af7Sopenharmony_ci 1014e5c31af7Sopenharmony_ci for (int vecNdx = 0; vecNdx < numVecs; vecNdx++) 1015e5c31af7Sopenharmony_ci { 1016e5c31af7Sopenharmony_ci const deUint32 curLoc = (deUint32)attribs.size(); 1017e5c31af7Sopenharmony_ci const deUint32 offset = (deUint32)(layoutEntry.offset + layoutEntry.vecStride*vecNdx); 1018e5c31af7Sopenharmony_ci const vk::VkVertexInputAttributeDescription desc = 1019e5c31af7Sopenharmony_ci { 1020e5c31af7Sopenharmony_ci curLoc, // location 1021e5c31af7Sopenharmony_ci 1u, // binding 1022e5c31af7Sopenharmony_ci vecFmt, // format 1023e5c31af7Sopenharmony_ci offset, // offset 1024e5c31af7Sopenharmony_ci }; 1025e5c31af7Sopenharmony_ci 1026e5c31af7Sopenharmony_ci attribs.push_back(desc); 1027e5c31af7Sopenharmony_ci } 1028e5c31af7Sopenharmony_ci } 1029e5c31af7Sopenharmony_ci 1030e5c31af7Sopenharmony_ci return attribs; 1031e5c31af7Sopenharmony_ci} 1032e5c31af7Sopenharmony_ci 1033e5c31af7Sopenharmony_ciMove<vk::VkPipeline> createPipeline (Context& context, 1034e5c31af7Sopenharmony_ci const vector<Value>& inputValues, 1035e5c31af7Sopenharmony_ci const ValueBufferLayout& inputLayout, 1036e5c31af7Sopenharmony_ci const PipelineProgram& program, 1037e5c31af7Sopenharmony_ci vk::VkRenderPass renderPass, 1038e5c31af7Sopenharmony_ci vk::VkPipelineLayout pipelineLayout, 1039e5c31af7Sopenharmony_ci tcu::UVec2 renderSize, 1040e5c31af7Sopenharmony_ci deUint32 size) 1041e5c31af7Sopenharmony_ci{ 1042e5c31af7Sopenharmony_ci const vk::VkShaderModule vertShader = program.hasShader(glu::SHADERTYPE_VERTEX) ? program.getShader(glu::SHADERTYPE_VERTEX) : DE_NULL; 1043e5c31af7Sopenharmony_ci const vk::VkShaderModule tessControlShader = program.hasShader(glu::SHADERTYPE_TESSELLATION_CONTROL) ? program.getShader(glu::SHADERTYPE_TESSELLATION_CONTROL) : DE_NULL; 1044e5c31af7Sopenharmony_ci const vk::VkShaderModule tessEvalShader = program.hasShader(glu::SHADERTYPE_TESSELLATION_EVALUATION) ? program.getShader(glu::SHADERTYPE_TESSELLATION_EVALUATION) : DE_NULL; 1045e5c31af7Sopenharmony_ci const vk::VkShaderModule geomShader = program.hasShader(glu::SHADERTYPE_GEOMETRY) ? program.getShader(glu::SHADERTYPE_GEOMETRY) : DE_NULL; 1046e5c31af7Sopenharmony_ci const vk::VkShaderModule fragShader = program.hasShader(glu::SHADERTYPE_FRAGMENT) ? program.getShader(glu::SHADERTYPE_FRAGMENT) : DE_NULL; 1047e5c31af7Sopenharmony_ci const vector<vk::VkVertexInputAttributeDescription> vertexAttribParams (getVertexAttributeDescriptions(inputValues, inputLayout)); 1048e5c31af7Sopenharmony_ci const vector<vk::VkViewport> viewports (1, vk::makeViewport(renderSize)); 1049e5c31af7Sopenharmony_ci const vector<vk::VkRect2D> scissors (1, vk::makeRect2D(renderSize)); 1050e5c31af7Sopenharmony_ci const vk::VkVertexInputBindingDescription vertexBindings[] = 1051e5c31af7Sopenharmony_ci { 1052e5c31af7Sopenharmony_ci { 1053e5c31af7Sopenharmony_ci 0u, // binding 1054e5c31af7Sopenharmony_ci (deUint32)sizeof(tcu::Vec2), // stride 1055e5c31af7Sopenharmony_ci vk::VK_VERTEX_INPUT_RATE_VERTEX, // stepRate 1056e5c31af7Sopenharmony_ci }, 1057e5c31af7Sopenharmony_ci { 1058e5c31af7Sopenharmony_ci 1u, // binding 1059e5c31af7Sopenharmony_ci 0u, // stride 1060e5c31af7Sopenharmony_ci vk::VK_VERTEX_INPUT_RATE_INSTANCE, // stepRate 1061e5c31af7Sopenharmony_ci }, 1062e5c31af7Sopenharmony_ci }; 1063e5c31af7Sopenharmony_ci const vk::VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 1064e5c31af7Sopenharmony_ci { 1065e5c31af7Sopenharmony_ci vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // sType 1066e5c31af7Sopenharmony_ci DE_NULL, // pNext 1067e5c31af7Sopenharmony_ci (vk::VkPipelineVertexInputStateCreateFlags)0, 1068e5c31af7Sopenharmony_ci (inputValues.empty() ? 1u : 2u), // bindingCount 1069e5c31af7Sopenharmony_ci vertexBindings, // pVertexBindingDescriptions 1070e5c31af7Sopenharmony_ci (deUint32)vertexAttribParams.size(), // attributeCount 1071e5c31af7Sopenharmony_ci &vertexAttribParams[0], // pVertexAttributeDescriptions 1072e5c31af7Sopenharmony_ci }; 1073e5c31af7Sopenharmony_ci const vk::VkColorComponentFlags allCompMask = vk::VK_COLOR_COMPONENT_R_BIT 1074e5c31af7Sopenharmony_ci | vk::VK_COLOR_COMPONENT_G_BIT 1075e5c31af7Sopenharmony_ci | vk::VK_COLOR_COMPONENT_B_BIT 1076e5c31af7Sopenharmony_ci | vk::VK_COLOR_COMPONENT_A_BIT; 1077e5c31af7Sopenharmony_ci vk::VkPipelineColorBlendAttachmentState attBlendParams[4]; 1078e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < size; i++) 1079e5c31af7Sopenharmony_ci { 1080e5c31af7Sopenharmony_ci vk::VkPipelineColorBlendAttachmentState blend = 1081e5c31af7Sopenharmony_ci { 1082e5c31af7Sopenharmony_ci VK_FALSE, // blendEnable 1083e5c31af7Sopenharmony_ci vk::VK_BLEND_FACTOR_ONE, // srcBlendColor 1084e5c31af7Sopenharmony_ci vk::VK_BLEND_FACTOR_ZERO, // destBlendColor 1085e5c31af7Sopenharmony_ci vk::VK_BLEND_OP_ADD, // blendOpColor 1086e5c31af7Sopenharmony_ci vk::VK_BLEND_FACTOR_ONE, // srcBlendAlpha 1087e5c31af7Sopenharmony_ci vk::VK_BLEND_FACTOR_ZERO, // destBlendAlpha 1088e5c31af7Sopenharmony_ci vk::VK_BLEND_OP_ADD, // blendOpAlpha 1089e5c31af7Sopenharmony_ci allCompMask, // componentWriteMask 1090e5c31af7Sopenharmony_ci }; 1091e5c31af7Sopenharmony_ci attBlendParams[i] = blend; 1092e5c31af7Sopenharmony_ci } 1093e5c31af7Sopenharmony_ci 1094e5c31af7Sopenharmony_ci const vk::VkPipelineColorBlendStateCreateInfo blendParams = 1095e5c31af7Sopenharmony_ci { 1096e5c31af7Sopenharmony_ci vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType 1097e5c31af7Sopenharmony_ci DE_NULL, // pNext 1098e5c31af7Sopenharmony_ci (vk::VkPipelineColorBlendStateCreateFlags)0, 1099e5c31af7Sopenharmony_ci VK_FALSE, // logicOpEnable 1100e5c31af7Sopenharmony_ci vk::VK_LOGIC_OP_COPY, // logicOp 1101e5c31af7Sopenharmony_ci size, // attachmentCount 1102e5c31af7Sopenharmony_ci &attBlendParams[0], // pAttachments 1103e5c31af7Sopenharmony_ci { 0.0f, 0.0f, 0.0f, 0.0f }, // blendConstants 1104e5c31af7Sopenharmony_ci }; 1105e5c31af7Sopenharmony_ci 1106e5c31af7Sopenharmony_ci return vk::makeGraphicsPipeline(context.getDeviceInterface(), // const DeviceInterface& vk 1107e5c31af7Sopenharmony_ci context.getDevice(), // const VkDevice device 1108e5c31af7Sopenharmony_ci pipelineLayout, // const VkPipelineLayout pipelineLayout 1109e5c31af7Sopenharmony_ci vertShader, // const VkShaderModule vertexShaderModule 1110e5c31af7Sopenharmony_ci tessControlShader, // const VkShaderModule tessellationControlShaderModule 1111e5c31af7Sopenharmony_ci tessEvalShader, // const VkShaderModule tessellationEvalShaderModule 1112e5c31af7Sopenharmony_ci geomShader, // const VkShaderModule geometryShaderModule 1113e5c31af7Sopenharmony_ci fragShader, // const VkShaderModule fragmentShaderModule 1114e5c31af7Sopenharmony_ci renderPass, // const VkRenderPass renderPass 1115e5c31af7Sopenharmony_ci viewports, // const std::vector<VkViewport>& viewports 1116e5c31af7Sopenharmony_ci scissors, // const std::vector<VkRect2D>& scissors 1117e5c31af7Sopenharmony_ci vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology 1118e5c31af7Sopenharmony_ci 0u, // const deUint32 subpass 1119e5c31af7Sopenharmony_ci 0u, // const deUint32 patchControlPoints 1120e5c31af7Sopenharmony_ci &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo 1121e5c31af7Sopenharmony_ci DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo 1122e5c31af7Sopenharmony_ci DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo 1123e5c31af7Sopenharmony_ci DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo 1124e5c31af7Sopenharmony_ci &blendParams); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo 1125e5c31af7Sopenharmony_ci} 1126e5c31af7Sopenharmony_ci 1127e5c31af7Sopenharmony_ciMove<vk::VkFramebuffer> createFramebuffer (Context& context, vk::VkRenderPass renderPass, Move<vk::VkImageView> colorAttView[4], deUint32 size, int width, int height) 1128e5c31af7Sopenharmony_ci{ 1129e5c31af7Sopenharmony_ci vk::VkImageView att[4]; 1130e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < size; i++) 1131e5c31af7Sopenharmony_ci { 1132e5c31af7Sopenharmony_ci att[i] = *colorAttView[i]; 1133e5c31af7Sopenharmony_ci } 1134e5c31af7Sopenharmony_ci const vk::VkFramebufferCreateInfo framebufferParams = 1135e5c31af7Sopenharmony_ci { 1136e5c31af7Sopenharmony_ci vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // sType 1137e5c31af7Sopenharmony_ci DE_NULL, // pNext 1138e5c31af7Sopenharmony_ci (vk::VkFramebufferCreateFlags)0, 1139e5c31af7Sopenharmony_ci renderPass, // renderPass 1140e5c31af7Sopenharmony_ci size, // attachmentCount 1141e5c31af7Sopenharmony_ci &att[0], // pAttachments 1142e5c31af7Sopenharmony_ci (deUint32)width, // width 1143e5c31af7Sopenharmony_ci (deUint32)height, // height 1144e5c31af7Sopenharmony_ci 1u, // layers 1145e5c31af7Sopenharmony_ci }; 1146e5c31af7Sopenharmony_ci 1147e5c31af7Sopenharmony_ci return vk::createFramebuffer(context.getDeviceInterface(), context.getDevice(), &framebufferParams); 1148e5c31af7Sopenharmony_ci} 1149e5c31af7Sopenharmony_ci 1150e5c31af7Sopenharmony_ciMove<vk::VkCommandPool> createCommandPool (Context& context) 1151e5c31af7Sopenharmony_ci{ 1152e5c31af7Sopenharmony_ci const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 1153e5c31af7Sopenharmony_ci 1154e5c31af7Sopenharmony_ci return vk::createCommandPool(context.getDeviceInterface(), context.getDevice(), (vk::VkCommandPoolCreateFlags)0u, queueFamilyIndex); 1155e5c31af7Sopenharmony_ci} 1156e5c31af7Sopenharmony_ci 1157e5c31af7Sopenharmony_ciMove<vk::VkDescriptorPool> createDescriptorPool (Context& context) 1158e5c31af7Sopenharmony_ci{ 1159e5c31af7Sopenharmony_ci return vk::DescriptorPoolBuilder() 1160e5c31af7Sopenharmony_ci .addType(vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2u) 1161e5c31af7Sopenharmony_ci .build(context.getDeviceInterface(), context.getDevice(), vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 1162e5c31af7Sopenharmony_ci} 1163e5c31af7Sopenharmony_ci 1164e5c31af7Sopenharmony_ciMove<vk::VkDescriptorSet> allocateDescriptorSet (Context& context, vk::VkDescriptorPool descriptorPool, vk::VkDescriptorSetLayout setLayout) 1165e5c31af7Sopenharmony_ci{ 1166e5c31af7Sopenharmony_ci const vk::VkDescriptorSetAllocateInfo params = 1167e5c31af7Sopenharmony_ci { 1168e5c31af7Sopenharmony_ci vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 1169e5c31af7Sopenharmony_ci DE_NULL, 1170e5c31af7Sopenharmony_ci descriptorPool, 1171e5c31af7Sopenharmony_ci 1u, 1172e5c31af7Sopenharmony_ci &setLayout 1173e5c31af7Sopenharmony_ci }; 1174e5c31af7Sopenharmony_ci 1175e5c31af7Sopenharmony_ci return vk::allocateDescriptorSet(context.getDeviceInterface(), context.getDevice(), ¶ms); 1176e5c31af7Sopenharmony_ci} 1177e5c31af7Sopenharmony_ci 1178e5c31af7Sopenharmony_ciMove<vk::VkCommandBuffer> allocateCommandBuffer (Context& context, vk::VkCommandPool cmdPool) 1179e5c31af7Sopenharmony_ci{ 1180e5c31af7Sopenharmony_ci return vk::allocateCommandBuffer(context.getDeviceInterface(), context.getDevice(), cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY); 1181e5c31af7Sopenharmony_ci} 1182e5c31af7Sopenharmony_ci 1183e5c31af7Sopenharmony_civk::VkFormat getRenderTargetFormat (DataType dataType) 1184e5c31af7Sopenharmony_ci{ 1185e5c31af7Sopenharmony_ci switch (dataType) 1186e5c31af7Sopenharmony_ci { 1187e5c31af7Sopenharmony_ci case glu::TYPE_FLOAT_VEC2: 1188e5c31af7Sopenharmony_ci return vk::VK_FORMAT_R8G8_UNORM; 1189e5c31af7Sopenharmony_ci case glu::TYPE_FLOAT_VEC3: 1190e5c31af7Sopenharmony_ci return vk::VK_FORMAT_R5G6B5_UNORM_PACK16; 1191e5c31af7Sopenharmony_ci case glu::TYPE_FLOAT_VEC4: 1192e5c31af7Sopenharmony_ci return vk::VK_FORMAT_R8G8B8A8_UNORM; 1193e5c31af7Sopenharmony_ci case glu::TYPE_INT_VEC2: 1194e5c31af7Sopenharmony_ci return vk::VK_FORMAT_R8G8_SINT; 1195e5c31af7Sopenharmony_ci case glu::TYPE_INT_VEC4: 1196e5c31af7Sopenharmony_ci return vk::VK_FORMAT_R8G8B8A8_SINT; 1197e5c31af7Sopenharmony_ci default: 1198e5c31af7Sopenharmony_ci return vk::VK_FORMAT_R8G8B8A8_UNORM; 1199e5c31af7Sopenharmony_ci } 1200e5c31af7Sopenharmony_ci} 1201e5c31af7Sopenharmony_ci 1202e5c31af7Sopenharmony_ciMovePtr<vk::Allocation> allocateAndBindMemory (Context& context, vk::VkImage image, vk::MemoryRequirement memReqs) 1203e5c31af7Sopenharmony_ci{ 1204e5c31af7Sopenharmony_ci const vk::DeviceInterface& vkd = context.getDeviceInterface(); 1205e5c31af7Sopenharmony_ci const vk::VkMemoryRequirements imgReqs = vk::getImageMemoryRequirements(vkd, context.getDevice(), image); 1206e5c31af7Sopenharmony_ci MovePtr<vk::Allocation> memory = context.getDefaultAllocator().allocate(imgReqs, memReqs); 1207e5c31af7Sopenharmony_ci 1208e5c31af7Sopenharmony_ci vkd.bindImageMemory(context.getDevice(), image, memory->getMemory(), memory->getOffset()); 1209e5c31af7Sopenharmony_ci 1210e5c31af7Sopenharmony_ci return memory; 1211e5c31af7Sopenharmony_ci} 1212e5c31af7Sopenharmony_ci 1213e5c31af7Sopenharmony_civoid writeValuesToMem (Context& context, const vk::Allocation& dst, const ValueBufferLayout& layout, const vector<Value>& values, int arrayNdx) 1214e5c31af7Sopenharmony_ci{ 1215e5c31af7Sopenharmony_ci copyToLayout(dst.getHostPtr(), layout, values, arrayNdx); 1216e5c31af7Sopenharmony_ci 1217e5c31af7Sopenharmony_ci // \note Buffers are not allocated with coherency / uncached requirement so we need to manually flush CPU write caches 1218e5c31af7Sopenharmony_ci flushAlloc(context.getDeviceInterface(), context.getDevice(), dst); 1219e5c31af7Sopenharmony_ci} 1220e5c31af7Sopenharmony_ci 1221e5c31af7Sopenharmony_ciclass ShaderCaseInstance : public TestInstance 1222e5c31af7Sopenharmony_ci{ 1223e5c31af7Sopenharmony_cipublic: 1224e5c31af7Sopenharmony_ci ShaderCaseInstance (Context& context, const ShaderCaseSpecification& spec); 1225e5c31af7Sopenharmony_ci ~ShaderCaseInstance (void); 1226e5c31af7Sopenharmony_ci 1227e5c31af7Sopenharmony_ci TestStatus iterate (void); 1228e5c31af7Sopenharmony_ci 1229e5c31af7Sopenharmony_ciprivate: 1230e5c31af7Sopenharmony_ci enum 1231e5c31af7Sopenharmony_ci { 1232e5c31af7Sopenharmony_ci RENDER_WIDTH = 64, 1233e5c31af7Sopenharmony_ci RENDER_HEIGHT = 64, 1234e5c31af7Sopenharmony_ci 1235e5c31af7Sopenharmony_ci POSITIONS_OFFSET = 0, 1236e5c31af7Sopenharmony_ci POSITIONS_SIZE = (int)sizeof(Vec2)*4, 1237e5c31af7Sopenharmony_ci 1238e5c31af7Sopenharmony_ci INDICES_OFFSET = POSITIONS_SIZE, 1239e5c31af7Sopenharmony_ci INDICES_SIZE = (int)sizeof(deUint16)*6, 1240e5c31af7Sopenharmony_ci 1241e5c31af7Sopenharmony_ci TOTAL_POS_NDX_SIZE = POSITIONS_SIZE+INDICES_SIZE 1242e5c31af7Sopenharmony_ci }; 1243e5c31af7Sopenharmony_ci 1244e5c31af7Sopenharmony_ci const ShaderCaseSpecification& m_spec; 1245e5c31af7Sopenharmony_ci 1246e5c31af7Sopenharmony_ci const Unique<vk::VkBuffer> m_posNdxBuffer; 1247e5c31af7Sopenharmony_ci const UniquePtr<vk::Allocation> m_posNdxMem; 1248e5c31af7Sopenharmony_ci 1249e5c31af7Sopenharmony_ci const ValueBufferLayout m_inputLayout; 1250e5c31af7Sopenharmony_ci const Unique<vk::VkBuffer> m_inputBuffer; // Input values (attributes). Can be NULL if no inputs present 1251e5c31af7Sopenharmony_ci const UniquePtr<vk::Allocation> m_inputMem; // Input memory, can be NULL if no input buffer exists 1252e5c31af7Sopenharmony_ci 1253e5c31af7Sopenharmony_ci const ValueBufferLayout m_referenceLayout; 1254e5c31af7Sopenharmony_ci const Unique<vk::VkBuffer> m_referenceBuffer; // Output (reference) values. Can be NULL if no outputs present 1255e5c31af7Sopenharmony_ci const UniquePtr<vk::Allocation> m_referenceMem; // Output (reference) memory, can be NULL if no reference buffer exists 1256e5c31af7Sopenharmony_ci 1257e5c31af7Sopenharmony_ci const ValueBufferLayout m_uniformLayout; 1258e5c31af7Sopenharmony_ci const Unique<vk::VkBuffer> m_uniformBuffer; // Uniform values. Can be NULL if no uniforms present 1259e5c31af7Sopenharmony_ci const UniquePtr<vk::Allocation> m_uniformMem; // Uniform memory, can be NULL if no uniform buffer exists 1260e5c31af7Sopenharmony_ci 1261e5c31af7Sopenharmony_ci const vk::VkFormat m_rtFormat; 1262e5c31af7Sopenharmony_ci deUint32 m_outputCount; 1263e5c31af7Sopenharmony_ci Move<vk::VkImage> m_rtImage [4]; 1264e5c31af7Sopenharmony_ci MovePtr<vk::Allocation> m_rtMem[4]; 1265e5c31af7Sopenharmony_ci Move<vk::VkImageView> m_rtView[4]; 1266e5c31af7Sopenharmony_ci 1267e5c31af7Sopenharmony_ci Move<vk::VkBuffer> m_readImageBuffer[4]; 1268e5c31af7Sopenharmony_ci MovePtr<vk::Allocation> m_readImageMem[4]; 1269e5c31af7Sopenharmony_ci 1270e5c31af7Sopenharmony_ci const Unique<vk::VkRenderPass> m_renderPass; 1271e5c31af7Sopenharmony_ci Move<vk::VkFramebuffer> m_framebuffer; 1272e5c31af7Sopenharmony_ci const PipelineProgram m_program; 1273e5c31af7Sopenharmony_ci const Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout; 1274e5c31af7Sopenharmony_ci const Unique<vk::VkPipelineLayout> m_pipelineLayout; 1275e5c31af7Sopenharmony_ci const Unique<vk::VkPipeline> m_pipeline; 1276e5c31af7Sopenharmony_ci 1277e5c31af7Sopenharmony_ci const Unique<vk::VkDescriptorPool> m_descriptorPool; 1278e5c31af7Sopenharmony_ci const Unique<vk::VkDescriptorSet> m_descriptorSet; 1279e5c31af7Sopenharmony_ci 1280e5c31af7Sopenharmony_ci const Unique<vk::VkCommandPool> m_cmdPool; 1281e5c31af7Sopenharmony_ci const Unique<vk::VkCommandBuffer> m_cmdBuffer; 1282e5c31af7Sopenharmony_ci 1283e5c31af7Sopenharmony_ci int m_subCaseNdx; 1284e5c31af7Sopenharmony_ci}; 1285e5c31af7Sopenharmony_ci 1286e5c31af7Sopenharmony_ciShaderCaseInstance::ShaderCaseInstance (Context& context, const ShaderCaseSpecification& spec) 1287e5c31af7Sopenharmony_ci : TestInstance (context) 1288e5c31af7Sopenharmony_ci , m_spec (spec) 1289e5c31af7Sopenharmony_ci 1290e5c31af7Sopenharmony_ci , m_posNdxBuffer (createBuffer(context, (vk::VkDeviceSize)TOTAL_POS_NDX_SIZE, vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT|vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)) 1291e5c31af7Sopenharmony_ci , m_posNdxMem (vk::bindBuffer (context.getDeviceInterface(), context.getDevice(),m_context.getDefaultAllocator(), *m_posNdxBuffer, vk::MemoryRequirement::HostVisible)) 1292e5c31af7Sopenharmony_ci 1293e5c31af7Sopenharmony_ci , m_inputLayout (computeStd430Layout(spec.values.inputs)) 1294e5c31af7Sopenharmony_ci , m_inputBuffer (m_inputLayout.size > 0 ? createBuffer(context, (vk::VkDeviceSize)m_inputLayout.size, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) : Move<vk::VkBuffer>()) 1295e5c31af7Sopenharmony_ci , m_inputMem (m_inputLayout.size > 0 ? vk::bindBuffer (context.getDeviceInterface(), context.getDevice(),m_context.getDefaultAllocator(), *m_inputBuffer, vk::MemoryRequirement::HostVisible) : MovePtr<vk::Allocation>()) 1296e5c31af7Sopenharmony_ci 1297e5c31af7Sopenharmony_ci , m_referenceLayout (computeStd140Layout(spec.values.outputs)) 1298e5c31af7Sopenharmony_ci , m_referenceBuffer (m_referenceLayout.size > 0 ? createBuffer(context, (vk::VkDeviceSize)m_referenceLayout.size, vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : Move<vk::VkBuffer>()) 1299e5c31af7Sopenharmony_ci , m_referenceMem (m_referenceLayout.size > 0 ? vk::bindBuffer (context.getDeviceInterface(), context.getDevice(),m_context.getDefaultAllocator(), *m_referenceBuffer, vk::MemoryRequirement::HostVisible) : MovePtr<vk::Allocation>()) 1300e5c31af7Sopenharmony_ci 1301e5c31af7Sopenharmony_ci , m_uniformLayout (computeStd140Layout(spec.values.uniforms)) 1302e5c31af7Sopenharmony_ci , m_uniformBuffer (m_uniformLayout.size > 0 ? createBuffer(context, (vk::VkDeviceSize)m_uniformLayout.size, vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : Move<vk::VkBuffer>()) 1303e5c31af7Sopenharmony_ci , m_uniformMem (m_uniformLayout.size > 0 ? vk::bindBuffer (context.getDeviceInterface(), context.getDevice(),m_context.getDefaultAllocator(), *m_uniformBuffer, vk::MemoryRequirement::HostVisible) : MovePtr<vk::Allocation>()) 1304e5c31af7Sopenharmony_ci 1305e5c31af7Sopenharmony_ci , m_rtFormat (getRenderTargetFormat(spec.outputFormat)) 1306e5c31af7Sopenharmony_ci , m_outputCount (((deUint32)m_spec.values.outputs.size() == 0 || m_spec.outputType == glu::sl::OUTPUT_RESULT) ? 1 : (deUint32)m_spec.values.outputs.size()) 1307e5c31af7Sopenharmony_ci , m_rtImage () 1308e5c31af7Sopenharmony_ci , m_rtMem () 1309e5c31af7Sopenharmony_ci , m_rtView () 1310e5c31af7Sopenharmony_ci 1311e5c31af7Sopenharmony_ci , m_readImageBuffer () 1312e5c31af7Sopenharmony_ci , m_readImageMem () 1313e5c31af7Sopenharmony_ci 1314e5c31af7Sopenharmony_ci , m_renderPass (createRenderPass(context, m_rtFormat, m_outputCount)) 1315e5c31af7Sopenharmony_ci , m_framebuffer () 1316e5c31af7Sopenharmony_ci , m_program (context, spec) 1317e5c31af7Sopenharmony_ci , m_descriptorSetLayout (createDescriptorSetLayout(context, m_program.getStages())) 1318e5c31af7Sopenharmony_ci , m_pipelineLayout (createPipelineLayout(context, *m_descriptorSetLayout)) 1319e5c31af7Sopenharmony_ci , m_pipeline (createPipeline(context, spec.values.inputs, m_inputLayout, m_program, *m_renderPass, *m_pipelineLayout, tcu::UVec2(RENDER_WIDTH, RENDER_HEIGHT), m_outputCount)) 1320e5c31af7Sopenharmony_ci 1321e5c31af7Sopenharmony_ci , m_descriptorPool (createDescriptorPool(context)) 1322e5c31af7Sopenharmony_ci , m_descriptorSet (allocateDescriptorSet(context, *m_descriptorPool, *m_descriptorSetLayout)) 1323e5c31af7Sopenharmony_ci 1324e5c31af7Sopenharmony_ci , m_cmdPool (createCommandPool(context)) 1325e5c31af7Sopenharmony_ci , m_cmdBuffer (allocateCommandBuffer(context, *m_cmdPool)) 1326e5c31af7Sopenharmony_ci 1327e5c31af7Sopenharmony_ci , m_subCaseNdx (0) 1328e5c31af7Sopenharmony_ci{ 1329e5c31af7Sopenharmony_ci { 1330e5c31af7Sopenharmony_ci // Initialize the resources for each color attachment needed by the shader 1331e5c31af7Sopenharmony_ci for (deUint32 outNdx = 0; outNdx < m_outputCount; outNdx++) 1332e5c31af7Sopenharmony_ci { 1333e5c31af7Sopenharmony_ci m_rtImage[outNdx] = createImage2D(context, RENDER_WIDTH, RENDER_HEIGHT, m_rtFormat, vk::VK_IMAGE_TILING_OPTIMAL, vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT| vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT); 1334e5c31af7Sopenharmony_ci m_rtMem[outNdx] = allocateAndBindMemory(context, *m_rtImage[outNdx], vk::MemoryRequirement::Any); 1335e5c31af7Sopenharmony_ci m_rtView[outNdx] = createAttachmentView(context, *m_rtImage[outNdx], m_rtFormat); 1336e5c31af7Sopenharmony_ci 1337e5c31af7Sopenharmony_ci m_readImageBuffer[outNdx] = createBuffer(context, (vk::VkDeviceSize)(RENDER_WIDTH * RENDER_HEIGHT * tcu::getPixelSize(vk::mapVkFormat(m_rtFormat))), vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT); 1338e5c31af7Sopenharmony_ci m_readImageMem[outNdx] = vk::bindBuffer (context.getDeviceInterface(), context.getDevice(),m_context.getDefaultAllocator(), *m_readImageBuffer[outNdx], vk::MemoryRequirement::HostVisible); 1339e5c31af7Sopenharmony_ci } 1340e5c31af7Sopenharmony_ci m_framebuffer = createFramebuffer(context, *m_renderPass, m_rtView, m_outputCount, RENDER_WIDTH, RENDER_HEIGHT); 1341e5c31af7Sopenharmony_ci } 1342e5c31af7Sopenharmony_ci 1343e5c31af7Sopenharmony_ci const vk::DeviceInterface& vkd = context.getDeviceInterface(); 1344e5c31af7Sopenharmony_ci const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 1345e5c31af7Sopenharmony_ci 1346e5c31af7Sopenharmony_ci { 1347e5c31af7Sopenharmony_ci const Vec2 s_positions[] = 1348e5c31af7Sopenharmony_ci { 1349e5c31af7Sopenharmony_ci Vec2(-1.0f, -1.0f), 1350e5c31af7Sopenharmony_ci Vec2(-1.0f, +1.0f), 1351e5c31af7Sopenharmony_ci Vec2(+1.0f, -1.0f), 1352e5c31af7Sopenharmony_ci Vec2(+1.0f, +1.0f) 1353e5c31af7Sopenharmony_ci }; 1354e5c31af7Sopenharmony_ci const deUint16 s_indices[] = 1355e5c31af7Sopenharmony_ci { 1356e5c31af7Sopenharmony_ci 0, 1, 2, 1357e5c31af7Sopenharmony_ci 1, 3, 2 1358e5c31af7Sopenharmony_ci }; 1359e5c31af7Sopenharmony_ci 1360e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(sizeof(s_positions) == POSITIONS_SIZE); 1361e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(sizeof(s_indices) == INDICES_SIZE); 1362e5c31af7Sopenharmony_ci 1363e5c31af7Sopenharmony_ci deMemcpy((deUint8*)m_posNdxMem->getHostPtr() + POSITIONS_OFFSET, &s_positions[0], sizeof(s_positions)); 1364e5c31af7Sopenharmony_ci deMemcpy((deUint8*)m_posNdxMem->getHostPtr() + INDICES_OFFSET, &s_indices[0], sizeof(s_indices)); 1365e5c31af7Sopenharmony_ci 1366e5c31af7Sopenharmony_ci flushAlloc(m_context.getDeviceInterface(), context.getDevice(), *m_posNdxMem); 1367e5c31af7Sopenharmony_ci } 1368e5c31af7Sopenharmony_ci 1369e5c31af7Sopenharmony_ci if (!m_spec.values.uniforms.empty()) 1370e5c31af7Sopenharmony_ci { 1371e5c31af7Sopenharmony_ci const vk::VkDescriptorBufferInfo bufInfo = 1372e5c31af7Sopenharmony_ci { 1373e5c31af7Sopenharmony_ci *m_uniformBuffer, 1374e5c31af7Sopenharmony_ci (vk::VkDeviceSize)0, // offset 1375e5c31af7Sopenharmony_ci (vk::VkDeviceSize)m_uniformLayout.size 1376e5c31af7Sopenharmony_ci }; 1377e5c31af7Sopenharmony_ci 1378e5c31af7Sopenharmony_ci vk::DescriptorSetUpdateBuilder() 1379e5c31af7Sopenharmony_ci .writeSingle(*m_descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(USER_UNIFORM_BINDING), 1380e5c31af7Sopenharmony_ci vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufInfo) 1381e5c31af7Sopenharmony_ci .update(vkd, m_context.getDevice()); 1382e5c31af7Sopenharmony_ci } 1383e5c31af7Sopenharmony_ci 1384e5c31af7Sopenharmony_ci if (!m_spec.values.outputs.empty()) 1385e5c31af7Sopenharmony_ci { 1386e5c31af7Sopenharmony_ci const vk::VkDescriptorBufferInfo bufInfo = 1387e5c31af7Sopenharmony_ci { 1388e5c31af7Sopenharmony_ci *m_referenceBuffer, 1389e5c31af7Sopenharmony_ci (vk::VkDeviceSize)0, // offset 1390e5c31af7Sopenharmony_ci (vk::VkDeviceSize)m_referenceLayout.size 1391e5c31af7Sopenharmony_ci }; 1392e5c31af7Sopenharmony_ci 1393e5c31af7Sopenharmony_ci vk::DescriptorSetUpdateBuilder() 1394e5c31af7Sopenharmony_ci .writeSingle(*m_descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(REFERENCE_UNIFORM_BINDING), 1395e5c31af7Sopenharmony_ci vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufInfo) 1396e5c31af7Sopenharmony_ci .update(vkd, m_context.getDevice()); 1397e5c31af7Sopenharmony_ci } 1398e5c31af7Sopenharmony_ci 1399e5c31af7Sopenharmony_ci // Record command buffer 1400e5c31af7Sopenharmony_ci 1401e5c31af7Sopenharmony_ci beginCommandBuffer(vkd, *m_cmdBuffer, 0u); 1402e5c31af7Sopenharmony_ci 1403e5c31af7Sopenharmony_ci { 1404e5c31af7Sopenharmony_ci const vk::VkMemoryBarrier vertFlushBarrier = 1405e5c31af7Sopenharmony_ci { 1406e5c31af7Sopenharmony_ci vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER, // sType 1407e5c31af7Sopenharmony_ci DE_NULL, // pNext 1408e5c31af7Sopenharmony_ci vk::VK_ACCESS_HOST_WRITE_BIT, // srcAccessMask 1409e5c31af7Sopenharmony_ci vk::VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT|vk::VK_ACCESS_UNIFORM_READ_BIT, // dstAccessMask 1410e5c31af7Sopenharmony_ci }; 1411e5c31af7Sopenharmony_ci vk::VkImageMemoryBarrier colorAttBarrier [4]; 1412e5c31af7Sopenharmony_ci for (deUint32 outNdx = 0; outNdx < m_outputCount; outNdx++) 1413e5c31af7Sopenharmony_ci { 1414e5c31af7Sopenharmony_ci vk::VkImageMemoryBarrier barrier = 1415e5c31af7Sopenharmony_ci { 1416e5c31af7Sopenharmony_ci vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType 1417e5c31af7Sopenharmony_ci DE_NULL, // pNext 1418e5c31af7Sopenharmony_ci 0u, // srcAccessMask 1419e5c31af7Sopenharmony_ci vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // dstAccessMask 1420e5c31af7Sopenharmony_ci vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout 1421e5c31af7Sopenharmony_ci vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout 1422e5c31af7Sopenharmony_ci queueFamilyIndex, // srcQueueFamilyIndex 1423e5c31af7Sopenharmony_ci queueFamilyIndex, // destQueueFamilyIndex 1424e5c31af7Sopenharmony_ci *m_rtImage[outNdx], // image 1425e5c31af7Sopenharmony_ci { 1426e5c31af7Sopenharmony_ci vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask 1427e5c31af7Sopenharmony_ci 0u, // baseMipLevel 1428e5c31af7Sopenharmony_ci 1u, // mipLevels 1429e5c31af7Sopenharmony_ci 0u, // baseArraySlice 1430e5c31af7Sopenharmony_ci 1u, // arraySize 1431e5c31af7Sopenharmony_ci } // subresourceRange 1432e5c31af7Sopenharmony_ci }; 1433e5c31af7Sopenharmony_ci colorAttBarrier[outNdx] = barrier; 1434e5c31af7Sopenharmony_ci } 1435e5c31af7Sopenharmony_ci vkd.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (vk::VkDependencyFlags)0, 1436e5c31af7Sopenharmony_ci 1, &vertFlushBarrier, 1437e5c31af7Sopenharmony_ci 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1438e5c31af7Sopenharmony_ci m_outputCount, &colorAttBarrier[0]); 1439e5c31af7Sopenharmony_ci } 1440e5c31af7Sopenharmony_ci 1441e5c31af7Sopenharmony_ci { 1442e5c31af7Sopenharmony_ci vk::VkClearValue clearValue[4]; 1443e5c31af7Sopenharmony_ci for (deUint32 outNdx = 0; outNdx < m_outputCount; outNdx++) 1444e5c31af7Sopenharmony_ci { 1445e5c31af7Sopenharmony_ci vk::VkClearValue value = vk::makeClearValueColorF32(0.125f, 0.25f, 0.75f, 1.0f); 1446e5c31af7Sopenharmony_ci clearValue[outNdx] = value; 1447e5c31af7Sopenharmony_ci } 1448e5c31af7Sopenharmony_ci beginRenderPass(vkd, *m_cmdBuffer, *m_renderPass, *m_framebuffer, vk::makeRect2D(0, 0, RENDER_WIDTH, RENDER_HEIGHT), m_outputCount, clearValue); 1449e5c31af7Sopenharmony_ci } 1450e5c31af7Sopenharmony_ci 1451e5c31af7Sopenharmony_ci vkd.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline); 1452e5c31af7Sopenharmony_ci 1453e5c31af7Sopenharmony_ci if (!m_spec.values.uniforms.empty() || !m_spec.values.outputs.empty()) 1454e5c31af7Sopenharmony_ci vkd.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &*m_descriptorSet, 0u, DE_NULL); 1455e5c31af7Sopenharmony_ci 1456e5c31af7Sopenharmony_ci { 1457e5c31af7Sopenharmony_ci const vk::VkBuffer buffers[] = { *m_posNdxBuffer, *m_inputBuffer }; 1458e5c31af7Sopenharmony_ci const vk::VkDeviceSize offsets[] = { POSITIONS_OFFSET, 0u }; 1459e5c31af7Sopenharmony_ci const deUint32 numBuffers = buffers[1] != 0 ? 2u : 1u; 1460e5c31af7Sopenharmony_ci vkd.cmdBindVertexBuffers(*m_cmdBuffer, 0u, numBuffers, buffers, offsets); 1461e5c31af7Sopenharmony_ci } 1462e5c31af7Sopenharmony_ci 1463e5c31af7Sopenharmony_ci vkd.cmdBindIndexBuffer (*m_cmdBuffer, *m_posNdxBuffer, (vk::VkDeviceSize)INDICES_OFFSET, vk::VK_INDEX_TYPE_UINT16); 1464e5c31af7Sopenharmony_ci vkd.cmdDrawIndexed (*m_cmdBuffer, 6u, 1u, 0u, 0u, 0u); 1465e5c31af7Sopenharmony_ci endRenderPass (vkd, *m_cmdBuffer); 1466e5c31af7Sopenharmony_ci 1467e5c31af7Sopenharmony_ci { 1468e5c31af7Sopenharmony_ci vk::VkImageMemoryBarrier renderFinishBarrier[4]; 1469e5c31af7Sopenharmony_ci for (deUint32 outNdx = 0; outNdx < m_outputCount; outNdx++) 1470e5c31af7Sopenharmony_ci { 1471e5c31af7Sopenharmony_ci vk::VkImageMemoryBarrier barrier = 1472e5c31af7Sopenharmony_ci { 1473e5c31af7Sopenharmony_ci vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType 1474e5c31af7Sopenharmony_ci DE_NULL, // pNext 1475e5c31af7Sopenharmony_ci vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask 1476e5c31af7Sopenharmony_ci vk::VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask 1477e5c31af7Sopenharmony_ci vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout 1478e5c31af7Sopenharmony_ci vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout 1479e5c31af7Sopenharmony_ci queueFamilyIndex, // srcQueueFamilyIndex 1480e5c31af7Sopenharmony_ci queueFamilyIndex, // destQueueFamilyIndex 1481e5c31af7Sopenharmony_ci *m_rtImage[outNdx], // image 1482e5c31af7Sopenharmony_ci { 1483e5c31af7Sopenharmony_ci vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask 1484e5c31af7Sopenharmony_ci 0u, // baseMipLevel 1485e5c31af7Sopenharmony_ci 1u, // mipLevels 1486e5c31af7Sopenharmony_ci 0u, // baseArraySlice 1487e5c31af7Sopenharmony_ci 1u, // arraySize 1488e5c31af7Sopenharmony_ci } // subresourceRange 1489e5c31af7Sopenharmony_ci }; 1490e5c31af7Sopenharmony_ci renderFinishBarrier[outNdx] = barrier; 1491e5c31af7Sopenharmony_ci } 1492e5c31af7Sopenharmony_ci 1493e5c31af7Sopenharmony_ci vkd.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0, 1494e5c31af7Sopenharmony_ci 0, (const vk::VkMemoryBarrier*)DE_NULL, 1495e5c31af7Sopenharmony_ci 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1496e5c31af7Sopenharmony_ci m_outputCount, &renderFinishBarrier[0]); 1497e5c31af7Sopenharmony_ci } 1498e5c31af7Sopenharmony_ci 1499e5c31af7Sopenharmony_ci { 1500e5c31af7Sopenharmony_ci for (deUint32 outNdx = 0; outNdx < m_outputCount; outNdx++) 1501e5c31af7Sopenharmony_ci { 1502e5c31af7Sopenharmony_ci const vk::VkBufferImageCopy copyParams = 1503e5c31af7Sopenharmony_ci { 1504e5c31af7Sopenharmony_ci (vk::VkDeviceSize)0u, // bufferOffset 1505e5c31af7Sopenharmony_ci (deUint32)RENDER_WIDTH, // bufferRowLength 1506e5c31af7Sopenharmony_ci (deUint32)RENDER_HEIGHT, // bufferImageHeight 1507e5c31af7Sopenharmony_ci { 1508e5c31af7Sopenharmony_ci vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspect 1509e5c31af7Sopenharmony_ci 0u, // mipLevel 1510e5c31af7Sopenharmony_ci 0u, // arrayLayer 1511e5c31af7Sopenharmony_ci 1u, // arraySize 1512e5c31af7Sopenharmony_ci }, // imageSubresource 1513e5c31af7Sopenharmony_ci { 0u, 0u, 0u }, // imageOffset 1514e5c31af7Sopenharmony_ci { RENDER_WIDTH, RENDER_HEIGHT, 1u } // imageExtent 1515e5c31af7Sopenharmony_ci }; 1516e5c31af7Sopenharmony_ci 1517e5c31af7Sopenharmony_ci vkd.cmdCopyImageToBuffer(*m_cmdBuffer, *m_rtImage[outNdx], vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_readImageBuffer[outNdx], 1u, ©Params); 1518e5c31af7Sopenharmony_ci } 1519e5c31af7Sopenharmony_ci } 1520e5c31af7Sopenharmony_ci 1521e5c31af7Sopenharmony_ci { 1522e5c31af7Sopenharmony_ci const vk::VkDeviceSize size = (vk::VkDeviceSize)(RENDER_WIDTH * RENDER_HEIGHT * tcu::getPixelSize(vk::mapVkFormat(m_rtFormat))); 1523e5c31af7Sopenharmony_ci vk::VkBufferMemoryBarrier copyFinishBarrier[4]; 1524e5c31af7Sopenharmony_ci for (deUint32 outNdx = 0; outNdx < m_outputCount; outNdx++) 1525e5c31af7Sopenharmony_ci { 1526e5c31af7Sopenharmony_ci vk::VkBufferMemoryBarrier barrier = 1527e5c31af7Sopenharmony_ci { 1528e5c31af7Sopenharmony_ci vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // sType 1529e5c31af7Sopenharmony_ci DE_NULL, // pNext 1530e5c31af7Sopenharmony_ci vk::VK_ACCESS_TRANSFER_WRITE_BIT, // srcAccessMask 1531e5c31af7Sopenharmony_ci vk::VK_ACCESS_HOST_READ_BIT, // dstAccessMask 1532e5c31af7Sopenharmony_ci queueFamilyIndex, // srcQueueFamilyIndex 1533e5c31af7Sopenharmony_ci queueFamilyIndex, // destQueueFamilyIndex 1534e5c31af7Sopenharmony_ci *m_readImageBuffer[outNdx], // buffer 1535e5c31af7Sopenharmony_ci 0u, // offset 1536e5c31af7Sopenharmony_ci size // size 1537e5c31af7Sopenharmony_ci }; 1538e5c31af7Sopenharmony_ci copyFinishBarrier[outNdx] = barrier; 1539e5c31af7Sopenharmony_ci } 1540e5c31af7Sopenharmony_ci vkd.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, (vk::VkDependencyFlags)0, 1541e5c31af7Sopenharmony_ci 0, (const vk::VkMemoryBarrier*)DE_NULL, 1542e5c31af7Sopenharmony_ci m_outputCount, ©FinishBarrier[0], 1543e5c31af7Sopenharmony_ci 0, (const vk::VkImageMemoryBarrier*)DE_NULL); 1544e5c31af7Sopenharmony_ci } 1545e5c31af7Sopenharmony_ci 1546e5c31af7Sopenharmony_ci endCommandBuffer(vkd, *m_cmdBuffer); 1547e5c31af7Sopenharmony_ci} 1548e5c31af7Sopenharmony_ci 1549e5c31af7Sopenharmony_ciShaderCaseInstance::~ShaderCaseInstance (void) 1550e5c31af7Sopenharmony_ci{ 1551e5c31af7Sopenharmony_ci} 1552e5c31af7Sopenharmony_ci 1553e5c31af7Sopenharmony_ciint getNumSubCases (const ValueBlock& values) 1554e5c31af7Sopenharmony_ci{ 1555e5c31af7Sopenharmony_ci if (!values.outputs.empty()) 1556e5c31af7Sopenharmony_ci return int(values.outputs[0].elements.size() / values.outputs[0].type.getScalarSize()); 1557e5c31af7Sopenharmony_ci else 1558e5c31af7Sopenharmony_ci return 1; // Always run at least one iteration even if no output values are specified 1559e5c31af7Sopenharmony_ci} 1560e5c31af7Sopenharmony_ci 1561e5c31af7Sopenharmony_cibool checkResultImage (const ConstPixelBufferAccess& result) 1562e5c31af7Sopenharmony_ci{ 1563e5c31af7Sopenharmony_ci const tcu::IVec4 refPix (255, 255, 255, 255); 1564e5c31af7Sopenharmony_ci 1565e5c31af7Sopenharmony_ci for (int y = 0; y < result.getHeight(); y++) 1566e5c31af7Sopenharmony_ci { 1567e5c31af7Sopenharmony_ci for (int x = 0; x < result.getWidth(); x++) 1568e5c31af7Sopenharmony_ci { 1569e5c31af7Sopenharmony_ci const tcu::IVec4 resPix = result.getPixelInt(x, y); 1570e5c31af7Sopenharmony_ci 1571e5c31af7Sopenharmony_ci if (boolAny(notEqual(resPix, refPix))) 1572e5c31af7Sopenharmony_ci return false; 1573e5c31af7Sopenharmony_ci } 1574e5c31af7Sopenharmony_ci } 1575e5c31af7Sopenharmony_ci 1576e5c31af7Sopenharmony_ci return true; 1577e5c31af7Sopenharmony_ci} 1578e5c31af7Sopenharmony_ci 1579e5c31af7Sopenharmony_cibool checkResultImageWithReference (const ConstPixelBufferAccess& result, tcu::IVec4 refPix) 1580e5c31af7Sopenharmony_ci{ 1581e5c31af7Sopenharmony_ci for (int y = 0; y < result.getHeight(); y++) 1582e5c31af7Sopenharmony_ci { 1583e5c31af7Sopenharmony_ci for (int x = 0; x < result.getWidth(); x++) 1584e5c31af7Sopenharmony_ci { 1585e5c31af7Sopenharmony_ci const tcu::IVec4 resPix = result.getPixelInt(x, y); 1586e5c31af7Sopenharmony_ci 1587e5c31af7Sopenharmony_ci if (boolAny(notEqual(resPix, refPix))) 1588e5c31af7Sopenharmony_ci return false; 1589e5c31af7Sopenharmony_ci } 1590e5c31af7Sopenharmony_ci } 1591e5c31af7Sopenharmony_ci 1592e5c31af7Sopenharmony_ci return true; 1593e5c31af7Sopenharmony_ci} 1594e5c31af7Sopenharmony_ciTestStatus ShaderCaseInstance::iterate (void) 1595e5c31af7Sopenharmony_ci{ 1596e5c31af7Sopenharmony_ci const vk::DeviceInterface& vkd = m_context.getDeviceInterface(); 1597e5c31af7Sopenharmony_ci const vk::VkDevice device = m_context.getDevice(); 1598e5c31af7Sopenharmony_ci const vk::VkQueue queue = m_context.getUniversalQueue(); 1599e5c31af7Sopenharmony_ci 1600e5c31af7Sopenharmony_ci if (!m_spec.values.inputs.empty()) 1601e5c31af7Sopenharmony_ci writeValuesToMem(m_context, *m_inputMem, m_inputLayout, m_spec.values.inputs, m_subCaseNdx); 1602e5c31af7Sopenharmony_ci 1603e5c31af7Sopenharmony_ci if (!m_spec.values.outputs.empty()) 1604e5c31af7Sopenharmony_ci writeValuesToMem(m_context, *m_referenceMem, m_referenceLayout, m_spec.values.outputs, m_subCaseNdx); 1605e5c31af7Sopenharmony_ci 1606e5c31af7Sopenharmony_ci if (!m_spec.values.uniforms.empty()) 1607e5c31af7Sopenharmony_ci writeValuesToMem(m_context, *m_uniformMem, m_uniformLayout, m_spec.values.uniforms, m_subCaseNdx); 1608e5c31af7Sopenharmony_ci 1609e5c31af7Sopenharmony_ci submitCommandsAndWait(vkd, device, queue, m_cmdBuffer.get()); 1610e5c31af7Sopenharmony_ci 1611e5c31af7Sopenharmony_ci // Result was checked in fragment shader 1612e5c31af7Sopenharmony_ci if (m_spec.outputType == glu::sl::OUTPUT_RESULT) 1613e5c31af7Sopenharmony_ci { 1614e5c31af7Sopenharmony_ci const ConstPixelBufferAccess imgAccess (TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), RENDER_WIDTH, RENDER_HEIGHT, 1, m_readImageMem[0]->getHostPtr()); 1615e5c31af7Sopenharmony_ci 1616e5c31af7Sopenharmony_ci invalidateAlloc(vkd, device, *m_readImageMem[0]); 1617e5c31af7Sopenharmony_ci 1618e5c31af7Sopenharmony_ci if (!checkResultImage(imgAccess)) 1619e5c31af7Sopenharmony_ci { 1620e5c31af7Sopenharmony_ci TestLog& log = m_context.getTestContext().getLog(); 1621e5c31af7Sopenharmony_ci 1622e5c31af7Sopenharmony_ci log << TestLog::Message << "ERROR: Got non-white pixels on sub-case " << m_subCaseNdx << TestLog::EndMessage 1623e5c31af7Sopenharmony_ci << TestLog::Image("Result", "Result", imgAccess); 1624e5c31af7Sopenharmony_ci 1625e5c31af7Sopenharmony_ci dumpValues(log, m_spec.values, m_subCaseNdx); 1626e5c31af7Sopenharmony_ci 1627e5c31af7Sopenharmony_ci return TestStatus::fail(string("Got invalid pixels at sub-case ") + de::toString(m_subCaseNdx)); 1628e5c31af7Sopenharmony_ci } 1629e5c31af7Sopenharmony_ci } 1630e5c31af7Sopenharmony_ci // Result was written to color buffer 1631e5c31af7Sopenharmony_ci else 1632e5c31af7Sopenharmony_ci { 1633e5c31af7Sopenharmony_ci for (deUint32 outNdx = 0; outNdx < m_outputCount; outNdx++) 1634e5c31af7Sopenharmony_ci { 1635e5c31af7Sopenharmony_ci const ConstPixelBufferAccess imgAccess (vk::mapVkFormat(m_rtFormat), RENDER_WIDTH, RENDER_HEIGHT, 1, m_readImageMem[outNdx]->getHostPtr()); 1636e5c31af7Sopenharmony_ci const DataType dataType = m_spec.values.outputs[outNdx].type.getBasicType(); 1637e5c31af7Sopenharmony_ci const int numComponents = getDataTypeScalarSize(dataType); 1638e5c31af7Sopenharmony_ci tcu::IVec4 reference (0, 0, 0, 1); 1639e5c31af7Sopenharmony_ci 1640e5c31af7Sopenharmony_ci for (int refNdx = 0; refNdx < numComponents; refNdx++) 1641e5c31af7Sopenharmony_ci { 1642e5c31af7Sopenharmony_ci if (isDataTypeFloatOrVec(dataType)) 1643e5c31af7Sopenharmony_ci reference[refNdx] = (int)m_spec.values.outputs[outNdx].elements[m_subCaseNdx * numComponents + refNdx].float32; 1644e5c31af7Sopenharmony_ci else if (isDataTypeIntOrIVec(dataType)) 1645e5c31af7Sopenharmony_ci reference[refNdx] = m_spec.values.outputs[outNdx].elements[m_subCaseNdx * numComponents + refNdx].int32; 1646e5c31af7Sopenharmony_ci else 1647e5c31af7Sopenharmony_ci DE_FATAL("Unknown data type"); 1648e5c31af7Sopenharmony_ci } 1649e5c31af7Sopenharmony_ci 1650e5c31af7Sopenharmony_ci invalidateAlloc(vkd, device, *m_readImageMem[outNdx]); 1651e5c31af7Sopenharmony_ci 1652e5c31af7Sopenharmony_ci if (!checkResultImageWithReference(imgAccess, reference)) 1653e5c31af7Sopenharmony_ci { 1654e5c31af7Sopenharmony_ci TestLog& log = m_context.getTestContext().getLog(); 1655e5c31af7Sopenharmony_ci 1656e5c31af7Sopenharmony_ci log << TestLog::Message << "ERROR: Got nonmatching pixels on sub-case " << m_subCaseNdx << " output " << outNdx << TestLog::EndMessage 1657e5c31af7Sopenharmony_ci << TestLog::Image("Result", "Result", imgAccess); 1658e5c31af7Sopenharmony_ci 1659e5c31af7Sopenharmony_ci dumpValues(log, m_spec.values, m_subCaseNdx); 1660e5c31af7Sopenharmony_ci 1661e5c31af7Sopenharmony_ci return TestStatus::fail(string("Got invalid pixels at sub-case ") + de::toString(m_subCaseNdx)); 1662e5c31af7Sopenharmony_ci } 1663e5c31af7Sopenharmony_ci } 1664e5c31af7Sopenharmony_ci } 1665e5c31af7Sopenharmony_ci 1666e5c31af7Sopenharmony_ci if (++m_subCaseNdx < getNumSubCases(m_spec.values)) 1667e5c31af7Sopenharmony_ci return TestStatus::incomplete(); 1668e5c31af7Sopenharmony_ci else 1669e5c31af7Sopenharmony_ci return TestStatus::pass("All sub-cases passed"); 1670e5c31af7Sopenharmony_ci} 1671e5c31af7Sopenharmony_ci 1672e5c31af7Sopenharmony_ciclass ShaderCase : public TestCase 1673e5c31af7Sopenharmony_ci{ 1674e5c31af7Sopenharmony_cipublic: 1675e5c31af7Sopenharmony_ci ShaderCase (tcu::TestContext& testCtx, const string& name, const string& description, const ShaderCaseSpecification& spec); 1676e5c31af7Sopenharmony_ci 1677e5c31af7Sopenharmony_ci 1678e5c31af7Sopenharmony_ci void initPrograms (SourceCollections& programCollection) const; 1679e5c31af7Sopenharmony_ci TestInstance* createInstance (Context& context) const; 1680e5c31af7Sopenharmony_ci 1681e5c31af7Sopenharmony_ciprivate: 1682e5c31af7Sopenharmony_ci const ShaderCaseSpecification m_spec; 1683e5c31af7Sopenharmony_ci}; 1684e5c31af7Sopenharmony_ci 1685e5c31af7Sopenharmony_ciShaderCase::ShaderCase (tcu::TestContext& testCtx, const string& name, const string& description, const ShaderCaseSpecification& spec) 1686e5c31af7Sopenharmony_ci : TestCase (testCtx, name, description) 1687e5c31af7Sopenharmony_ci , m_spec (spec) 1688e5c31af7Sopenharmony_ci{ 1689e5c31af7Sopenharmony_ci} 1690e5c31af7Sopenharmony_ci 1691e5c31af7Sopenharmony_civoid ShaderCase::initPrograms (SourceCollections& sourceCollection) const 1692e5c31af7Sopenharmony_ci{ 1693e5c31af7Sopenharmony_ci vector<ProgramSources> specializedSources (m_spec.programs.size()); 1694e5c31af7Sopenharmony_ci 1695e5c31af7Sopenharmony_ci DE_ASSERT(isValid(m_spec)); 1696e5c31af7Sopenharmony_ci 1697e5c31af7Sopenharmony_ci if (m_spec.expectResult != glu::sl::EXPECT_PASS) 1698e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Only EXPECT_PASS is supported"); 1699e5c31af7Sopenharmony_ci 1700e5c31af7Sopenharmony_ci if (m_spec.caseType == glu::sl::CASETYPE_VERTEX_ONLY) 1701e5c31af7Sopenharmony_ci { 1702e5c31af7Sopenharmony_ci DE_ASSERT(m_spec.programs.size() == 1 && m_spec.programs[0].sources.sources[glu::SHADERTYPE_VERTEX].size() == 1); 1703e5c31af7Sopenharmony_ci specializedSources[0] << glu::VertexSource(specializeVertexShader(m_spec, m_spec.programs[0].sources.sources[glu::SHADERTYPE_VERTEX][0])) 1704e5c31af7Sopenharmony_ci << glu::FragmentSource(genFragmentShader(m_spec)); 1705e5c31af7Sopenharmony_ci } 1706e5c31af7Sopenharmony_ci else if (m_spec.caseType == glu::sl::CASETYPE_FRAGMENT_ONLY) 1707e5c31af7Sopenharmony_ci { 1708e5c31af7Sopenharmony_ci DE_ASSERT(m_spec.programs.size() == 1 && m_spec.programs[0].sources.sources[glu::SHADERTYPE_FRAGMENT].size() == 1); 1709e5c31af7Sopenharmony_ci specializedSources[0] << glu::VertexSource(genVertexShader(m_spec)) 1710e5c31af7Sopenharmony_ci << glu::FragmentSource(specializeFragmentShader(m_spec, m_spec.programs[0].sources.sources[glu::SHADERTYPE_FRAGMENT][0])); 1711e5c31af7Sopenharmony_ci } 1712e5c31af7Sopenharmony_ci else 1713e5c31af7Sopenharmony_ci { 1714e5c31af7Sopenharmony_ci DE_ASSERT(m_spec.caseType == glu::sl::CASETYPE_COMPLETE); 1715e5c31af7Sopenharmony_ci 1716e5c31af7Sopenharmony_ci const int maxPatchVertices = 4; // \todo [2015-08-05 pyry] Query 1717e5c31af7Sopenharmony_ci 1718e5c31af7Sopenharmony_ci for (size_t progNdx = 0; progNdx < m_spec.programs.size(); progNdx++) 1719e5c31af7Sopenharmony_ci { 1720e5c31af7Sopenharmony_ci const ProgramSpecializationParams progSpecParams (m_spec, m_spec.programs[progNdx].requiredExtensions, maxPatchVertices); 1721e5c31af7Sopenharmony_ci 1722e5c31af7Sopenharmony_ci specializeProgramSources(specializedSources[progNdx], m_spec.programs[progNdx].sources, progSpecParams); 1723e5c31af7Sopenharmony_ci } 1724e5c31af7Sopenharmony_ci } 1725e5c31af7Sopenharmony_ci 1726e5c31af7Sopenharmony_ci for (size_t progNdx = 0; progNdx < specializedSources.size(); progNdx++) 1727e5c31af7Sopenharmony_ci { 1728e5c31af7Sopenharmony_ci for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; shaderType++) 1729e5c31af7Sopenharmony_ci { 1730e5c31af7Sopenharmony_ci if (!specializedSources[progNdx].sources[shaderType].empty()) 1731e5c31af7Sopenharmony_ci { 1732e5c31af7Sopenharmony_ci vk::GlslSource& curSrc = sourceCollection.glslSources.add(getShaderName((glu::ShaderType)shaderType, progNdx)); 1733e5c31af7Sopenharmony_ci curSrc.sources[shaderType] = specializedSources[progNdx].sources[shaderType]; 1734e5c31af7Sopenharmony_ci } 1735e5c31af7Sopenharmony_ci } 1736e5c31af7Sopenharmony_ci } 1737e5c31af7Sopenharmony_ci} 1738e5c31af7Sopenharmony_ci 1739e5c31af7Sopenharmony_ciTestInstance* ShaderCase::createInstance (Context& context) const 1740e5c31af7Sopenharmony_ci{ 1741e5c31af7Sopenharmony_ci return new ShaderCaseInstance(context, m_spec); 1742e5c31af7Sopenharmony_ci} 1743e5c31af7Sopenharmony_ci 1744e5c31af7Sopenharmony_ciclass ShaderCaseFactory : public glu::sl::ShaderCaseFactory 1745e5c31af7Sopenharmony_ci{ 1746e5c31af7Sopenharmony_cipublic: 1747e5c31af7Sopenharmony_ci ShaderCaseFactory (tcu::TestContext& testCtx) 1748e5c31af7Sopenharmony_ci : m_testCtx(testCtx) 1749e5c31af7Sopenharmony_ci { 1750e5c31af7Sopenharmony_ci } 1751e5c31af7Sopenharmony_ci 1752e5c31af7Sopenharmony_ci tcu::TestCaseGroup* createGroup (const string& name, const string& description, const vector<tcu::TestNode*>& children) 1753e5c31af7Sopenharmony_ci { 1754e5c31af7Sopenharmony_ci return new tcu::TestCaseGroup(m_testCtx, name.c_str(), description.c_str(), children); 1755e5c31af7Sopenharmony_ci } 1756e5c31af7Sopenharmony_ci 1757e5c31af7Sopenharmony_ci tcu::TestCase* createCase (const string& name, const string& description, const ShaderCaseSpecification& spec) 1758e5c31af7Sopenharmony_ci { 1759e5c31af7Sopenharmony_ci return new ShaderCase(m_testCtx, name, description, spec); 1760e5c31af7Sopenharmony_ci } 1761e5c31af7Sopenharmony_ci 1762e5c31af7Sopenharmony_ciprivate: 1763e5c31af7Sopenharmony_ci tcu::TestContext& m_testCtx; 1764e5c31af7Sopenharmony_ci}; 1765e5c31af7Sopenharmony_ci 1766e5c31af7Sopenharmony_ciclass ShaderLibraryGroup : public tcu::TestCaseGroup 1767e5c31af7Sopenharmony_ci{ 1768e5c31af7Sopenharmony_cipublic: 1769e5c31af7Sopenharmony_ci ShaderLibraryGroup (tcu::TestContext& testCtx, const string& name, const string& description, const string& filename) 1770e5c31af7Sopenharmony_ci : tcu::TestCaseGroup (testCtx, name.c_str(), description.c_str()) 1771e5c31af7Sopenharmony_ci , m_filename (filename) 1772e5c31af7Sopenharmony_ci { 1773e5c31af7Sopenharmony_ci } 1774e5c31af7Sopenharmony_ci 1775e5c31af7Sopenharmony_ci void init (void) 1776e5c31af7Sopenharmony_ci { 1777e5c31af7Sopenharmony_ci ShaderCaseFactory caseFactory (m_testCtx); 1778e5c31af7Sopenharmony_ci const vector<tcu::TestNode*> children = glu::sl::parseFile(m_testCtx.getArchive(), m_filename, &caseFactory); 1779e5c31af7Sopenharmony_ci 1780e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < children.size(); ndx++) 1781e5c31af7Sopenharmony_ci { 1782e5c31af7Sopenharmony_ci try 1783e5c31af7Sopenharmony_ci { 1784e5c31af7Sopenharmony_ci addChild(children[ndx]); 1785e5c31af7Sopenharmony_ci } 1786e5c31af7Sopenharmony_ci catch (...) 1787e5c31af7Sopenharmony_ci { 1788e5c31af7Sopenharmony_ci for (; ndx < children.size(); ndx++) 1789e5c31af7Sopenharmony_ci delete children[ndx]; 1790e5c31af7Sopenharmony_ci throw; 1791e5c31af7Sopenharmony_ci } 1792e5c31af7Sopenharmony_ci } 1793e5c31af7Sopenharmony_ci } 1794e5c31af7Sopenharmony_ci 1795e5c31af7Sopenharmony_ciprivate: 1796e5c31af7Sopenharmony_ci const string m_filename; 1797e5c31af7Sopenharmony_ci}; 1798e5c31af7Sopenharmony_ci 1799e5c31af7Sopenharmony_ci} // anonymous 1800e5c31af7Sopenharmony_ci 1801e5c31af7Sopenharmony_ciMovePtr<tcu::TestCaseGroup> createShaderLibraryGroup (tcu::TestContext& testCtx, const string& name, const string& description, const string& filename) 1802e5c31af7Sopenharmony_ci{ 1803e5c31af7Sopenharmony_ci return MovePtr<tcu::TestCaseGroup>(new ShaderLibraryGroup(testCtx, name, description, filename)); 1804e5c31af7Sopenharmony_ci} 1805e5c31af7Sopenharmony_ci 1806e5c31af7Sopenharmony_ci} // vkt 1807