1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2016 The Khronos Group Inc. 6 * Copyright (c) 2016 Samsung Electronics Co., Ltd. 7 * Copyright (c) 2014 The Android Open Source Project 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 *//*! 22 * \file 23 * \brief Texture test utilities. 24 *//*--------------------------------------------------------------------*/ 25 26 #include "vktTextureTestUtil.hpp" 27 28 #include "deFilePath.hpp" 29 #include "deMath.h" 30 #include "tcuCompressedTexture.hpp" 31 #include "tcuImageIO.hpp" 32 #include "tcuStringTemplate.hpp" 33 #include "tcuTestLog.hpp" 34 #include "vkBuilderUtil.hpp" 35 #include "vkImageUtil.hpp" 36 #include "vkPrograms.hpp" 37 #include "vkQueryUtil.hpp" 38 #include "vkRefUtil.hpp" 39 #include "vkTypeUtil.hpp" 40 #include "vkCmdUtil.hpp" 41 #include "vkObjUtil.hpp" 42 #include <map> 43 #include <string> 44 #include <vector> 45 46 using tcu::TestLog; 47 48 using namespace vk; 49 using namespace glu::TextureTestUtil; 50 51 namespace vkt 52 { 53 namespace texture 54 { 55 namespace util 56 { 57 58 deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance, VkPhysicalDevice physicalDevice, VkQueueFlags requiredCaps) 59 { 60 const std::vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice); 61 62 for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++) 63 { 64 if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps) 65 return (deUint32)queueNdx; 66 } 67 68 TCU_THROW(NotSupportedError, "No matching queue found"); 69 } 70 71 struct ShaderParameters { 72 float bias; //!< User-supplied bias. 73 float ref; //!< Reference value for shadow lookups. 74 tcu::Vec2 padding; //!< Shader uniform padding. 75 tcu::Vec4 colorScale; //!< Scale for texture color values. 76 tcu::Vec4 colorBias; //!< Bias for texture color values. 77 }; 78 79 const char* getProgramName(Program program) 80 { 81 switch (program) 82 { 83 case PROGRAM_2D_FLOAT: return "2D_FLOAT"; 84 case PROGRAM_2D_INT: return "2D_INT"; 85 case PROGRAM_2D_UINT: return "2D_UINT"; 86 case PROGRAM_2D_SHADOW: return "2D_SHADOW"; 87 case PROGRAM_2D_FLOAT_BIAS: return "2D_FLOAT_BIAS"; 88 case PROGRAM_2D_INT_BIAS: return "2D_INT_BIAS"; 89 case PROGRAM_2D_UINT_BIAS: return "2D_UINT_BIAS"; 90 case PROGRAM_2D_SHADOW_BIAS: return "2D_SHADOW_BIAS"; 91 case PROGRAM_1D_FLOAT: return "1D_FLOAT"; 92 case PROGRAM_1D_INT: return "1D_INT"; 93 case PROGRAM_1D_UINT: return "1D_UINT"; 94 case PROGRAM_1D_SHADOW: return "1D_SHADOW"; 95 case PROGRAM_1D_FLOAT_BIAS: return "1D_FLOAT_BIAS"; 96 case PROGRAM_1D_INT_BIAS: return "1D_INT_BIAS"; 97 case PROGRAM_1D_UINT_BIAS: return "1D_UINT_BIAS"; 98 case PROGRAM_1D_SHADOW_BIAS: return "1D_SHADOW_BIAS"; 99 case PROGRAM_CUBE_FLOAT: return "CUBE_FLOAT"; 100 case PROGRAM_CUBE_INT: return "CUBE_INT"; 101 case PROGRAM_CUBE_UINT: return "CUBE_UINT"; 102 case PROGRAM_CUBE_SHADOW: return "CUBE_SHADOW"; 103 case PROGRAM_CUBE_FLOAT_BIAS: return "CUBE_FLOAT_BIAS"; 104 case PROGRAM_CUBE_INT_BIAS: return "CUBE_INT_BIAS"; 105 case PROGRAM_CUBE_UINT_BIAS: return "CUBE_UINT_BIAS"; 106 case PROGRAM_CUBE_SHADOW_BIAS: return "CUBE_SHADOW_BIAS"; 107 case PROGRAM_2D_ARRAY_FLOAT: return "2D_ARRAY_FLOAT"; 108 case PROGRAM_2D_ARRAY_INT: return "2D_ARRAY_INT"; 109 case PROGRAM_2D_ARRAY_UINT: return "2D_ARRAY_UINT"; 110 case PROGRAM_2D_ARRAY_SHADOW: return "2D_ARRAY_SHADOW"; 111 case PROGRAM_3D_FLOAT: return "3D_FLOAT"; 112 case PROGRAM_3D_INT: return "3D_INT"; 113 case PROGRAM_3D_UINT: return "3D_UINT"; 114 case PROGRAM_3D_FLOAT_BIAS: return "3D_FLOAT_BIAS"; 115 case PROGRAM_3D_INT_BIAS: return "3D_INT_BIAS"; 116 case PROGRAM_3D_UINT_BIAS: return "3D_UINT_BIAS"; 117 case PROGRAM_CUBE_ARRAY_FLOAT: return "CUBE_ARRAY_FLOAT"; 118 case PROGRAM_CUBE_ARRAY_INT: return "CUBE_ARRAY_INT"; 119 case PROGRAM_CUBE_ARRAY_UINT: return "CUBE_ARRAY_UINT"; 120 case PROGRAM_CUBE_ARRAY_SHADOW: return "CUBE_ARRAY_SHADOW"; 121 case PROGRAM_1D_ARRAY_FLOAT: return "1D_ARRAY_FLOAT"; 122 case PROGRAM_1D_ARRAY_INT: return "1D_ARRAY_INT"; 123 case PROGRAM_1D_ARRAY_UINT: return "1D_ARRAY_UINT"; 124 case PROGRAM_1D_ARRAY_SHADOW: return "1D_ARRAY_SHADOW"; 125 case PROGRAM_BUFFER_FLOAT: return "BUFFER_FLOAT"; 126 case PROGRAM_BUFFER_INT: return "BUFFER_INT"; 127 case PROGRAM_BUFFER_UINT: return "BUFFER_UINT"; 128 default: 129 DE_ASSERT(false); 130 } 131 return NULL; 132 } 133 134 VkImageViewType textureTypeToImageViewType (TextureBinding::Type type) 135 { 136 switch (type) 137 { 138 case TextureBinding::TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D; 139 case TextureBinding::TYPE_2D_ARRAY: return VK_IMAGE_VIEW_TYPE_2D_ARRAY; 140 case TextureBinding::TYPE_CUBE_MAP: return VK_IMAGE_VIEW_TYPE_CUBE; 141 case TextureBinding::TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D; 142 default: 143 DE_ASSERT(false); 144 } 145 146 return VK_IMAGE_VIEW_TYPE_2D; 147 } 148 149 VkImageType imageViewTypeToImageType (VkImageViewType type) 150 { 151 switch (type) 152 { 153 case VK_IMAGE_VIEW_TYPE_2D: 154 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: 155 case VK_IMAGE_VIEW_TYPE_CUBE: return VK_IMAGE_TYPE_2D; 156 case VK_IMAGE_VIEW_TYPE_3D: return VK_IMAGE_TYPE_3D; 157 default: 158 DE_ASSERT(false); 159 } 160 161 return VK_IMAGE_TYPE_2D; 162 } 163 164 void initializePrograms(vk::SourceCollections& programCollection, glu::Precision texCoordPrecision, const std::vector<Program>& programs) 165 { 166 static const char* vertShaderTemplate = 167 "${VTX_HEADER}" 168 "layout(location = 0) ${VTX_IN} highp vec4 a_position;\n" 169 "layout(location = 1) ${VTX_IN} ${PRECISION} ${TEXCOORD_TYPE} a_texCoord;\n" 170 "layout(location = 0) ${VTX_OUT} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n" 171 "${VTX_OUT} gl_PerVertex { vec4 gl_Position; };\n" 172 "\n" 173 "void main (void)\n" 174 "{\n" 175 " gl_Position = a_position;\n" 176 " v_texCoord = a_texCoord;\n" 177 "}\n"; 178 179 static const char* fragShaderTemplate = 180 "${FRAG_HEADER}" 181 "layout(location = 0) ${FRAG_IN} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n" 182 "layout(location = 0) out mediump vec4 ${FRAG_COLOR};\n" 183 "layout (set=0, binding=0, std140) uniform Block \n" 184 "{\n" 185 " ${PRECISION} float u_bias;\n" 186 " ${PRECISION} float u_ref;\n" 187 " ${PRECISION} vec4 u_colorScale;\n" 188 " ${PRECISION} vec4 u_colorBias;\n" 189 "};\n\n" 190 "layout (set=1, binding=0) uniform ${PRECISION} ${SAMPLER_TYPE} u_sampler;\n" 191 "void main (void)\n" 192 "{\n" 193 " ${FRAG_COLOR} = ${LOOKUP} * u_colorScale + u_colorBias;\n" 194 "}\n"; 195 196 tcu::StringTemplate vertexSource (vertShaderTemplate); 197 tcu::StringTemplate fragmentSource (fragShaderTemplate); 198 199 for (std::vector<Program>::const_iterator programIt = programs.begin(); programIt != programs.end(); ++programIt) 200 { 201 Program program = *programIt; 202 std::map<std::string, std::string> params; 203 204 bool isCube = de::inRange<int>(program, PROGRAM_CUBE_FLOAT, PROGRAM_CUBE_SHADOW_BIAS); 205 bool isArray = de::inRange<int>(program, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_2D_ARRAY_SHADOW) 206 || de::inRange<int>(program, PROGRAM_1D_ARRAY_FLOAT, PROGRAM_1D_ARRAY_SHADOW); 207 208 bool is1D = de::inRange<int>(program, PROGRAM_1D_FLOAT, PROGRAM_1D_SHADOW_BIAS) 209 || de::inRange<int>(program, PROGRAM_1D_ARRAY_FLOAT, PROGRAM_1D_ARRAY_SHADOW) 210 || de::inRange<int>(program, PROGRAM_BUFFER_FLOAT, PROGRAM_BUFFER_UINT); 211 212 bool is2D = de::inRange<int>(program, PROGRAM_2D_FLOAT, PROGRAM_2D_SHADOW_BIAS) 213 || de::inRange<int>(program, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_2D_ARRAY_SHADOW); 214 215 bool is3D = de::inRange<int>(program, PROGRAM_3D_FLOAT, PROGRAM_3D_UINT_BIAS); 216 bool isCubeArray = de::inRange<int>(program, PROGRAM_CUBE_ARRAY_FLOAT, PROGRAM_CUBE_ARRAY_SHADOW); 217 218 const std::string version = glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450); 219 220 params["FRAG_HEADER"] = version + "\n"; 221 params["VTX_HEADER"] = version + "\n"; 222 params["VTX_IN"] = "in"; 223 params["VTX_OUT"] = "out"; 224 params["FRAG_IN"] = "in"; 225 params["FRAG_COLOR"] = "dEQP_FragColor"; 226 227 params["PRECISION"] = glu::getPrecisionName(texCoordPrecision); 228 229 if (isCubeArray) 230 params["TEXCOORD_TYPE"] = "vec4"; 231 else if (isCube || (is2D && isArray) || is3D) 232 params["TEXCOORD_TYPE"] = "vec3"; 233 else if ((is1D && isArray) || is2D) 234 params["TEXCOORD_TYPE"] = "vec2"; 235 else if (is1D) 236 params["TEXCOORD_TYPE"] = "float"; 237 else 238 DE_ASSERT(DE_FALSE); 239 240 const char* sampler = DE_NULL; 241 const char* lookup = DE_NULL; 242 243 switch (program) 244 { 245 case PROGRAM_2D_FLOAT: sampler = "sampler2D"; lookup = "texture(u_sampler, v_texCoord)"; break; 246 case PROGRAM_2D_INT: sampler = "isampler2D"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break; 247 case PROGRAM_2D_UINT: sampler = "usampler2D"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break; 248 case PROGRAM_2D_SHADOW: sampler = "sampler2DShadow"; lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref)), 0.0, 0.0, 1.0)"; break; 249 case PROGRAM_2D_FLOAT_BIAS: sampler = "sampler2D"; lookup = "texture(u_sampler, v_texCoord, u_bias)"; break; 250 case PROGRAM_2D_INT_BIAS: sampler = "isampler2D"; lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))"; break; 251 case PROGRAM_2D_UINT_BIAS: sampler = "usampler2D"; lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))"; break; 252 case PROGRAM_2D_SHADOW_BIAS: sampler = "sampler2DShadow"; lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)"; break; 253 case PROGRAM_1D_FLOAT: sampler = "sampler1D"; lookup = "texture(u_sampler, v_texCoord)"; break; 254 case PROGRAM_1D_INT: sampler = "isampler1D"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break; 255 case PROGRAM_1D_UINT: sampler = "usampler1D"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break; 256 case PROGRAM_1D_SHADOW: sampler = "sampler1DShadow"; lookup = "vec4(texture(u_sampler, vec3(v_texCoord, 0.0, u_ref)), 0.0, 0.0, 1.0)"; break; 257 case PROGRAM_1D_FLOAT_BIAS: sampler = "sampler1D"; lookup = "texture(u_sampler, v_texCoord, u_bias)"; break; 258 case PROGRAM_1D_INT_BIAS: sampler = "isampler1D"; lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))"; break; 259 case PROGRAM_1D_UINT_BIAS: sampler = "usampler1D"; lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))"; break; 260 case PROGRAM_1D_SHADOW_BIAS: sampler = "sampler1DShadow"; lookup = "vec4(texture(u_sampler, vec3(v_texCoord, 0.0, u_ref), u_bias), 0.0, 0.0, 1.0)"; break; 261 case PROGRAM_CUBE_FLOAT: sampler = "samplerCube"; lookup = "texture(u_sampler, v_texCoord)"; break; 262 case PROGRAM_CUBE_INT: sampler = "isamplerCube"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break; 263 case PROGRAM_CUBE_UINT: sampler = "usamplerCube"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break; 264 case PROGRAM_CUBE_SHADOW: sampler = "samplerCubeShadow"; lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)"; break; 265 case PROGRAM_CUBE_FLOAT_BIAS: sampler = "samplerCube"; lookup = "texture(u_sampler, v_texCoord, u_bias)"; break; 266 case PROGRAM_CUBE_INT_BIAS: sampler = "isamplerCube"; lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))"; break; 267 case PROGRAM_CUBE_UINT_BIAS: sampler = "usamplerCube"; lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))"; break; 268 case PROGRAM_CUBE_SHADOW_BIAS: sampler = "samplerCubeShadow"; lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)"; break; 269 case PROGRAM_2D_ARRAY_FLOAT: sampler = "sampler2DArray"; lookup = "texture(u_sampler, v_texCoord)"; break; 270 case PROGRAM_2D_ARRAY_INT: sampler = "isampler2DArray"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break; 271 case PROGRAM_2D_ARRAY_UINT: sampler = "usampler2DArray"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break; 272 case PROGRAM_2D_ARRAY_SHADOW: sampler = "sampler2DArrayShadow"; lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)"; break; 273 case PROGRAM_3D_FLOAT: sampler = "sampler3D"; lookup = "texture(u_sampler, v_texCoord)"; break; 274 case PROGRAM_3D_INT: sampler = "isampler3D"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break; 275 case PROGRAM_3D_UINT: sampler = "usampler3D"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break; 276 case PROGRAM_3D_FLOAT_BIAS: sampler = "sampler3D"; lookup = "texture(u_sampler, v_texCoord, u_bias)"; break; 277 case PROGRAM_3D_INT_BIAS: sampler = "isampler3D"; lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))"; break; 278 case PROGRAM_3D_UINT_BIAS: sampler = "usampler3D"; lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))"; break; 279 case PROGRAM_CUBE_ARRAY_FLOAT: sampler = "samplerCubeArray"; lookup = "texture(u_sampler, v_texCoord)"; break; 280 case PROGRAM_CUBE_ARRAY_INT: sampler = "isamplerCubeArray"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break; 281 case PROGRAM_CUBE_ARRAY_UINT: sampler = "usamplerCubeArray"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break; 282 case PROGRAM_CUBE_ARRAY_SHADOW: sampler = "samplerCubeArrayShadow"; lookup = "vec4(texture(u_sampler, v_texCoord, u_ref), 0.0, 0.0, 1.0)"; break; 283 case PROGRAM_1D_ARRAY_FLOAT: sampler = "sampler1DArray"; lookup = "texture(u_sampler, v_texCoord)"; break; 284 case PROGRAM_1D_ARRAY_INT: sampler = "isampler1DArray"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break; 285 case PROGRAM_1D_ARRAY_UINT: sampler = "usampler1DArray"; lookup = "vec4(texture(u_sampler, v_texCoord))"; break; 286 case PROGRAM_1D_ARRAY_SHADOW: sampler = "sampler1DArrayShadow"; lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref)), 0.0, 0.0, 1.0)"; break; 287 case PROGRAM_BUFFER_FLOAT: sampler = "samplerBuffer"; lookup = "texelFetch(u_sampler, int(v_texCoord))"; break; 288 case PROGRAM_BUFFER_INT: sampler = "isamplerBuffer"; lookup = "vec4(texelFetch(u_sampler, int(v_texCoord)))"; break; 289 case PROGRAM_BUFFER_UINT: sampler = "usamplerBuffer"; lookup = "vec4(texelFetch(u_sampler, int(v_texCoord)))"; break; 290 default: 291 DE_ASSERT(false); 292 } 293 294 params["SAMPLER_TYPE"] = sampler; 295 params["LOOKUP"] = lookup; 296 297 programCollection.glslSources.add("vertext_" + std::string(getProgramName(program))) << glu::VertexSource(vertexSource.specialize(params)); 298 programCollection.glslSources.add("fragment_" + std::string(getProgramName(program))) << glu::FragmentSource(fragmentSource.specialize(params)); 299 } 300 } 301 302 TextureBinding::TextureBinding (Context& context) 303 : m_context (context) 304 { 305 } 306 307 TextureBinding::TextureBinding (Context& context, const TestTextureSp& textureData, const TextureBinding::Type type, const TextureBinding::ImageBackingMode backingMode, const VkComponentMapping componentMapping) 308 : m_context (context) 309 , m_type (type) 310 , m_backingMode (backingMode) 311 , m_textureData (textureData) 312 , m_componentMapping (componentMapping) 313 { 314 updateTextureData(m_textureData, m_type); 315 } 316 317 void TextureBinding::updateTextureData (const TestTextureSp& textureData, const TextureBinding::Type textureType) 318 { 319 const DeviceInterface& vkd = m_context.getDeviceInterface(); 320 const VkDevice vkDevice = m_context.getDevice(); 321 const bool sparse = m_backingMode == IMAGE_BACKING_MODE_SPARSE; 322 const deUint32 queueFamilyIndices[] = {m_context.getUniversalQueueFamilyIndex(), m_context.getSparseQueueFamilyIndex()}; 323 Allocator& allocator = m_context.getDefaultAllocator(); 324 m_type = textureType; 325 m_textureData = textureData; 326 327 const bool isCube = m_type == TYPE_CUBE_MAP; 328 VkImageCreateFlags imageCreateFlags = (isCube ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0) | (sparse ? (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) : 0); 329 const VkImageViewType imageViewType = textureTypeToImageViewType(textureType); 330 const VkImageType imageType = imageViewTypeToImageType(imageViewType); 331 const VkImageTiling imageTiling = VK_IMAGE_TILING_OPTIMAL; 332 const VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 333 const VkFormat format = textureData->isCompressed() ? mapCompressedTextureFormat(textureData->getCompressedLevel(0, 0).getFormat()) : mapTextureFormat(textureData->getTextureFormat()); 334 const tcu::UVec3 textureDimension = textureData->getTextureDimension(); 335 const deUint32 mipLevels = textureData->getNumLevels(); 336 const deUint32 arraySize = textureData->getArraySize(); 337 vk::VkImageFormatProperties imageFormatProperties; 338 const VkResult imageFormatQueryResult = m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(), format, imageType, imageTiling, imageUsageFlags, imageCreateFlags, &imageFormatProperties); 339 const VkSharingMode sharingMode = (sparse && m_context.getUniversalQueueFamilyIndex() != m_context.getSparseQueueFamilyIndex()) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE; 340 341 if (imageFormatQueryResult == VK_ERROR_FORMAT_NOT_SUPPORTED) 342 { 343 TCU_THROW(NotSupportedError, (std::string("Format not supported: ") + vk::getFormatName(format)).c_str()); 344 } 345 else 346 VK_CHECK(imageFormatQueryResult); 347 348 if (sparse) 349 { 350 deUint32 numSparseImageProperties = 0; 351 m_context.getInstanceInterface().getPhysicalDeviceSparseImageFormatProperties(m_context.getPhysicalDevice(), format, imageType, VK_SAMPLE_COUNT_1_BIT, imageUsageFlags, imageTiling, &numSparseImageProperties, DE_NULL); 352 if (numSparseImageProperties == 0) 353 TCU_THROW(NotSupportedError, (std::string("Sparse format not supported: ") + vk::getFormatName(format)).c_str()); 354 } 355 356 if (imageFormatProperties.maxArrayLayers < arraySize) 357 TCU_THROW(NotSupportedError, ("Maximum array layers number for this format is not enough for this test.")); 358 359 if (imageFormatProperties.maxMipLevels < mipLevels) 360 TCU_THROW(NotSupportedError, ("Maximum mimap level number for this format is not enough for this test.")); 361 362 if (imageFormatProperties.maxExtent.width < textureDimension.x() || 363 imageFormatProperties.maxExtent.height < textureDimension.y() || 364 imageFormatProperties.maxExtent.depth < textureDimension.z()) 365 { 366 TCU_THROW(NotSupportedError, ("Maximum image dimension for this format is not enough for this test.")); 367 } 368 369 // Create image 370 const VkImageCreateInfo imageParams = 371 { 372 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 373 DE_NULL, // const void* pNext; 374 imageCreateFlags, // VkImageCreateFlags flags; 375 imageType, // VkImageType imageType; 376 format, // VkFormat format; 377 { // VkExtent3D extent; 378 (deUint32)textureDimension.x(), 379 (deUint32)textureDimension.y(), 380 (deUint32)textureDimension.z() 381 }, 382 mipLevels, // deUint32 mipLevels; 383 arraySize, // deUint32 arrayLayers; 384 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 385 imageTiling, // VkImageTiling tiling; 386 imageUsageFlags, // VkImageUsageFlags usage; 387 sharingMode, // VkSharingMode sharingMode; 388 sharingMode == VK_SHARING_MODE_CONCURRENT ? 2u : 1u, // deUint32 queueFamilyIndexCount; 389 queueFamilyIndices, // const deUint32* pQueueFamilyIndices; 390 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 391 }; 392 393 m_textureImage = createImage(vkd, vkDevice, &imageParams); 394 395 if (sparse) 396 { 397 pipeline::uploadTestTextureSparse (vkd, 398 vkDevice, 399 m_context.getPhysicalDevice(), 400 m_context.getInstanceInterface(), 401 imageParams, 402 m_context.getUniversalQueue(), 403 m_context.getUniversalQueueFamilyIndex(), 404 m_context.getSparseQueue(), 405 allocator, 406 m_allocations, 407 *m_textureData, 408 *m_textureImage); 409 } 410 else 411 { 412 m_textureImageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_textureImage), MemoryRequirement::Any); 413 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_textureImage, m_textureImageMemory->getMemory(), m_textureImageMemory->getOffset())); 414 415 pipeline::uploadTestTexture (vkd, 416 vkDevice, 417 m_context.getUniversalQueue(), 418 m_context.getUniversalQueueFamilyIndex(), 419 allocator, 420 *m_textureData, 421 *m_textureImage); 422 } 423 424 updateTextureViewMipLevels(0, mipLevels - 1); 425 } 426 427 void TextureBinding::updateTextureViewMipLevels (deUint32 baseLevel, deUint32 maxLevel) 428 { 429 const DeviceInterface& vkd = m_context.getDeviceInterface(); 430 const VkDevice vkDevice = m_context.getDevice(); 431 const vk::VkImageViewType imageViewType = textureTypeToImageViewType(m_type); 432 const vk::VkFormat format = m_textureData->isCompressed() ? mapCompressedTextureFormat(m_textureData->getCompressedLevel(0, 0).getFormat()) : mapTextureFormat(m_textureData->getTextureFormat()); 433 const bool isShadowTexture = tcu::hasDepthComponent(m_textureData->getTextureFormat().order); 434 const VkImageAspectFlags aspectMask = isShadowTexture ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; 435 const deUint32 layerCount = m_textureData->getArraySize(); 436 const vk::VkImageViewCreateInfo viewParams = 437 { 438 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 439 NULL, // const voide* pNext; 440 0u, // VkImageViewCreateFlags flags; 441 *m_textureImage, // VkImage image; 442 imageViewType, // VkImageViewType viewType; 443 format, // VkFormat format; 444 m_componentMapping, // VkComponentMapping components; 445 { 446 aspectMask, // VkImageAspectFlags aspectMask; 447 baseLevel, // deUint32 baseMipLevel; 448 maxLevel-baseLevel+1, // deUint32 levelCount; 449 0, // deUint32 baseArrayLayer; 450 layerCount // deUint32 layerCount; 451 }, // VkImageSubresourceRange subresourceRange; 452 }; 453 454 m_textureImageView = createImageView(vkd, vkDevice, &viewParams); 455 } 456 457 const deUint16 TextureRenderer::s_vertexIndices[6] = { 0, 1, 2, 2, 1, 3 }; 458 const VkDeviceSize TextureRenderer::s_vertexIndexBufferSize = sizeof(TextureRenderer::s_vertexIndices); 459 460 TextureRenderer::TextureRenderer (Context& context, VkSampleCountFlagBits sampleCount, deUint32 renderWidth, deUint32 renderHeight, VkComponentMapping componentMapping) 461 : m_context (context) 462 , m_log (context.getTestContext().getLog()) 463 , m_renderWidth (renderWidth) 464 , m_renderHeight (renderHeight) 465 , m_sampleCount (sampleCount) 466 , m_multisampling (m_sampleCount != VK_SAMPLE_COUNT_1_BIT) 467 , m_imageFormat (VK_FORMAT_R8G8B8A8_UNORM) 468 , m_textureFormat (vk::mapVkFormat(m_imageFormat)) 469 , m_uniformBufferSize (sizeof(ShaderParameters)) 470 , m_resultBufferSize (renderWidth * renderHeight * m_textureFormat.getPixelSize()) 471 , m_viewportOffsetX (0.0f) 472 , m_viewportOffsetY (0.0f) 473 , m_viewportWidth ((float)renderWidth) 474 , m_viewportHeight ((float)renderHeight) 475 , m_componentMapping (componentMapping) 476 { 477 const DeviceInterface& vkd = m_context.getDeviceInterface(); 478 const VkDevice vkDevice = m_context.getDevice(); 479 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 480 Allocator& allocator = m_context.getDefaultAllocator(); 481 482 // Command Pool 483 m_commandPool = createCommandPool(vkd, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex); 484 485 // Image 486 { 487 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 488 VkImageFormatProperties properties; 489 490 if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(), 491 m_imageFormat, 492 VK_IMAGE_TYPE_2D, 493 VK_IMAGE_TILING_OPTIMAL, 494 imageUsage, 495 0, 496 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)) 497 { 498 TCU_THROW(NotSupportedError, "Format not supported"); 499 } 500 501 if ((properties.sampleCounts & m_sampleCount) != m_sampleCount) 502 { 503 TCU_THROW(NotSupportedError, "Format not supported"); 504 } 505 506 const VkImageCreateInfo imageCreateInfo = 507 { 508 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 509 DE_NULL, // const void* pNext; 510 0u, // VkImageCreateFlags flags; 511 VK_IMAGE_TYPE_2D, // VkImageType imageType; 512 m_imageFormat, // VkFormat format; 513 { m_renderWidth, m_renderHeight, 1u }, // VkExtent3D extent; 514 1u, // deUint32 mipLevels; 515 1u, // deUint32 arrayLayers; 516 m_sampleCount, // VkSampleCountFlagBits samples; 517 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 518 imageUsage, // VkImageUsageFlags usage; 519 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 520 1u, // deUint32 queueFamilyIndexCount; 521 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 522 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 523 }; 524 525 m_image = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL); 526 527 m_imageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_image), MemoryRequirement::Any); 528 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_image, m_imageMemory->getMemory(), m_imageMemory->getOffset())); 529 } 530 531 // Image View 532 { 533 const VkImageViewCreateInfo imageViewCreateInfo = 534 { 535 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 536 DE_NULL, // const void* pNext; 537 0u, // VkImageViewCreateFlags flags; 538 *m_image, // VkImage image; 539 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 540 m_imageFormat, // VkFormat format; 541 makeComponentMappingRGBA(), // VkComponentMapping components; 542 { 543 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 544 0u, // deUint32 baseMipLevel; 545 1u, // deUint32 mipLevels; 546 0u, // deUint32 baseArrayLayer; 547 1u, // deUint32 arraySize; 548 }, // VkImageSubresourceRange subresourceRange; 549 }; 550 551 m_imageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL); 552 } 553 554 if (m_multisampling) 555 { 556 { 557 // Resolved Image 558 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 559 VkImageFormatProperties properties; 560 561 if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(), 562 m_imageFormat, 563 VK_IMAGE_TYPE_2D, 564 VK_IMAGE_TILING_OPTIMAL, 565 imageUsage, 566 0, 567 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)) 568 { 569 TCU_THROW(NotSupportedError, "Format not supported"); 570 } 571 572 const VkImageCreateInfo imageCreateInfo = 573 { 574 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 575 DE_NULL, // const void* pNext; 576 0u, // VkImageCreateFlags flags; 577 VK_IMAGE_TYPE_2D, // VkImageType imageType; 578 m_imageFormat, // VkFormat format; 579 { m_renderWidth, m_renderHeight, 1u }, // VkExtent3D extent; 580 1u, // deUint32 mipLevels; 581 1u, // deUint32 arrayLayers; 582 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 583 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 584 imageUsage, // VkImageUsageFlags usage; 585 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 586 1u, // deUint32 queueFamilyIndexCount; 587 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 588 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 589 }; 590 591 m_resolvedImage = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL); 592 m_resolvedImageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_resolvedImage), MemoryRequirement::Any); 593 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_resolvedImage, m_resolvedImageMemory->getMemory(), m_resolvedImageMemory->getOffset())); 594 } 595 596 // Resolved Image View 597 { 598 const VkImageViewCreateInfo imageViewCreateInfo = 599 { 600 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 601 DE_NULL, // const void* pNext; 602 0u, // VkImageViewCreateFlags flags; 603 *m_resolvedImage, // VkImage image; 604 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 605 m_imageFormat, // VkFormat format; 606 makeComponentMappingRGBA(), // VkComponentMapping components; 607 { 608 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 609 0u, // deUint32 baseMipLevel; 610 1u, // deUint32 mipLevels; 611 0u, // deUint32 baseArrayLayer; 612 1u, // deUint32 arraySize; 613 }, // VkImageSubresourceRange subresourceRange; 614 }; 615 616 m_resolvedImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL); 617 } 618 } 619 620 // Render Pass 621 { 622 const VkImageLayout imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 623 const VkAttachmentDescription attachmentDesc[] = 624 { 625 { 626 0u, // VkAttachmentDescriptionFlags flags; 627 m_imageFormat, // VkFormat format; 628 m_sampleCount, // VkSampleCountFlagBits samples; 629 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp; 630 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 631 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 632 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 633 imageLayout, // VkImageLayout initialLayout; 634 imageLayout, // VkImageLayout finalLayout; 635 }, 636 { 637 0u, // VkAttachmentDescriptionFlags flags; 638 m_imageFormat, // VkFormat format; 639 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 640 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; 641 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 642 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 643 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 644 imageLayout, // VkImageLayout initialLayout; 645 imageLayout, // VkImageLayout finalLayout; 646 } 647 }; 648 649 const VkAttachmentReference attachmentRef = 650 { 651 0u, // deUint32 attachment; 652 imageLayout, // VkImageLayout layout; 653 }; 654 655 const VkAttachmentReference resolveAttachmentRef = 656 { 657 1u, // deUint32 attachment; 658 imageLayout, // VkImageLayout layout; 659 }; 660 661 const VkSubpassDescription subpassDesc = 662 { 663 0u, // VkSubpassDescriptionFlags flags; 664 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 665 0u, // deUint32 inputAttachmentCount; 666 DE_NULL, // const VkAttachmentReference* pInputAttachments; 667 1u, // deUint32 colorAttachmentCount; 668 &attachmentRef, // const VkAttachmentReference* pColorAttachments; 669 m_multisampling ? &resolveAttachmentRef : DE_NULL, // const VkAttachmentReference* pResolveAttachments; 670 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; 671 0u, // deUint32 preserveAttachmentCount; 672 DE_NULL, // const VkAttachmentReference* pPreserveAttachments; 673 }; 674 675 const VkRenderPassCreateInfo renderPassCreateInfo = 676 { 677 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 678 DE_NULL, // const void* pNext; 679 0u, // VkRenderPassCreateFlags flags; 680 m_multisampling ? 2u : 1u, // deUint32 attachmentCount; 681 attachmentDesc, // const VkAttachmentDescription* pAttachments; 682 1u, // deUint32 subpassCount; 683 &subpassDesc, // const VkSubpassDescription* pSubpasses; 684 0u, // deUint32 dependencyCount; 685 DE_NULL, // const VkSubpassDependency* pDependencies; 686 }; 687 688 m_renderPass = createRenderPass(vkd, vkDevice, &renderPassCreateInfo, DE_NULL); 689 } 690 691 // Vertex index buffer 692 { 693 const VkBufferCreateInfo indexBufferParams = 694 { 695 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 696 DE_NULL, // const void* pNext; 697 0u, // VkBufferCreateFlags flags; 698 s_vertexIndexBufferSize, // VkDeviceSize size; 699 VK_BUFFER_USAGE_INDEX_BUFFER_BIT, // VkBufferUsageFlags usage; 700 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 701 1u, // deUint32 queueFamilyCount; 702 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 703 }; 704 705 m_vertexIndexBuffer = createBuffer(vkd, vkDevice, &indexBufferParams); 706 m_vertexIndexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_vertexIndexBuffer), MemoryRequirement::HostVisible); 707 708 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_vertexIndexBuffer, m_vertexIndexBufferMemory->getMemory(), m_vertexIndexBufferMemory->getOffset())); 709 710 // Load vertices into vertex buffer 711 deMemcpy(m_vertexIndexBufferMemory->getHostPtr(), s_vertexIndices, s_vertexIndexBufferSize); 712 flushMappedMemoryRange(vkd, vkDevice, m_vertexIndexBufferMemory->getMemory(), m_vertexIndexBufferMemory->getOffset(), VK_WHOLE_SIZE); 713 } 714 715 // FrameBuffer 716 { 717 const VkImageView attachments[] = 718 { 719 *m_imageView, 720 *m_resolvedImageView, 721 }; 722 723 const VkFramebufferCreateInfo framebufferCreateInfo = 724 { 725 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 726 DE_NULL, // const void* pNext; 727 0u, // VkFramebufferCreateFlags flags; 728 *m_renderPass, // VkRenderPass renderPass; 729 m_multisampling ? 2u : 1u, // deUint32 attachmentCount; 730 attachments, // const VkImageView* pAttachments; 731 m_renderWidth, // deUint32 width; 732 m_renderHeight, // deUint32 height; 733 1u, // deUint32 layers; 734 }; 735 736 m_frameBuffer = createFramebuffer(vkd, vkDevice, &framebufferCreateInfo, DE_NULL); 737 } 738 739 // Uniform Buffer 740 { 741 const VkBufferCreateInfo bufferCreateInfo = 742 { 743 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 744 DE_NULL, // const void* pNext; 745 0u, // VkBufferCreateFlags flags; 746 m_uniformBufferSize, // VkDeviceSize size; 747 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage; 748 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 749 1u, // deUint32 queueFamilyIndexCount; 750 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 751 }; 752 753 m_uniformBuffer = createBuffer(vkd, vkDevice, &bufferCreateInfo); 754 m_uniformBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_uniformBuffer), MemoryRequirement::HostVisible); 755 756 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_uniformBuffer, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset())); 757 } 758 759 // DescriptorPool 760 { 761 DescriptorPoolBuilder descriptorPoolBuilder; 762 763 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); 764 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); 765 m_descriptorPool = descriptorPoolBuilder.build(vkd, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 2u); 766 } 767 768 // Result Buffer 769 { 770 const VkBufferCreateInfo bufferCreateInfo = 771 { 772 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 773 DE_NULL, // const void* pNext; 774 0u, // VkBufferCreateFlags flags; 775 m_resultBufferSize, // VkDeviceSize size; 776 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 777 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 778 1u, // deUint32 queueFamilyIndexCount; 779 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 780 }; 781 782 m_resultBuffer = createBuffer(vkd, vkDevice, &bufferCreateInfo); 783 m_resultBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_resultBuffer), MemoryRequirement::HostVisible); 784 785 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_resultBuffer, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset())); 786 } 787 788 clearImage(*m_image); 789 if(m_multisampling) 790 clearImage(*m_resolvedImage); 791 } 792 793 TextureRenderer::~TextureRenderer (void) 794 { 795 } 796 797 void TextureRenderer::clearImage(VkImage image) 798 { 799 const DeviceInterface& vkd = m_context.getDeviceInterface(); 800 const VkDevice vkDevice = m_context.getDevice(); 801 Move<VkCommandBuffer> commandBuffer; 802 const VkQueue queue = m_context.getUniversalQueue(); 803 804 const VkImageSubresourceRange subResourcerange = 805 { 806 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 807 0, // deUint32 baseMipLevel; 808 1, // deUint32 levelCount; 809 0, // deUint32 baseArrayLayer; 810 1 // deUint32 layerCount; 811 }; 812 813 commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 814 815 beginCommandBuffer(vkd, *commandBuffer); 816 817 addImageTransitionBarrier(*commandBuffer, image, 818 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask 819 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask 820 0, // VkAccessFlags srcAccessMask 821 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask 822 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 823 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); // VkImageLayout newLayout; 824 825 VkClearColorValue color = makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f).color; 826 vkd.cmdClearColorImage(*commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &color, 1, &subResourcerange); 827 828 addImageTransitionBarrier(*commandBuffer, image, 829 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags srcStageMask 830 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask 831 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask 832 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask 833 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 834 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout; 835 836 endCommandBuffer(vkd, *commandBuffer); 837 838 submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get()); 839 } 840 841 void TextureRenderer::add2DTexture (const TestTexture2DSp& texture, TextureBinding::ImageBackingMode backingMode) 842 { 843 m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_2D, backingMode, m_componentMapping))); 844 } 845 846 void TextureRenderer::addCubeTexture (const TestTextureCubeSp& texture, TextureBinding::ImageBackingMode backingMode) 847 { 848 m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_CUBE_MAP, backingMode, m_componentMapping))); 849 } 850 851 void TextureRenderer::add2DArrayTexture (const TestTexture2DArraySp& texture, TextureBinding::ImageBackingMode backingMode) 852 { 853 m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_2D_ARRAY, backingMode, m_componentMapping))); 854 } 855 856 void TextureRenderer::add3DTexture (const TestTexture3DSp& texture, TextureBinding::ImageBackingMode backingMode) 857 { 858 m_textureBindings.push_back(TextureBindingSp(new TextureBinding(m_context, texture, TextureBinding::TYPE_3D, backingMode, m_componentMapping))); 859 } 860 861 const pipeline::TestTexture2D& TextureRenderer::get2DTexture (int textureIndex) const 862 { 863 DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex); 864 DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_2D); 865 866 return dynamic_cast<const pipeline::TestTexture2D&>(m_textureBindings[textureIndex]->getTestTexture()); 867 } 868 869 const pipeline::TestTextureCube& TextureRenderer::getCubeTexture (int textureIndex) const 870 { 871 DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex); 872 DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_CUBE_MAP); 873 874 return dynamic_cast<const pipeline::TestTextureCube&>(m_textureBindings[textureIndex]->getTestTexture()); 875 } 876 877 const pipeline::TestTexture2DArray& TextureRenderer::get2DArrayTexture (int textureIndex) const 878 { 879 DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex); 880 DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_2D_ARRAY); 881 882 return dynamic_cast<const pipeline::TestTexture2DArray&>(m_textureBindings[textureIndex]->getTestTexture()); 883 } 884 885 const pipeline::TestTexture3D& TextureRenderer::get3DTexture (int textureIndex) const 886 { 887 DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex); 888 DE_ASSERT(m_textureBindings[textureIndex]->getType() == TextureBinding::TYPE_3D); 889 890 return dynamic_cast<const pipeline::TestTexture3D&>(m_textureBindings[textureIndex]->getTestTexture()); 891 } 892 893 void TextureRenderer::setViewport (float viewportX, float viewportY, float viewportW, float viewportH) 894 { 895 m_viewportHeight = viewportH; 896 m_viewportWidth = viewportW; 897 m_viewportOffsetX = viewportX; 898 m_viewportOffsetY = viewportY; 899 } 900 901 TextureBinding* TextureRenderer::getTextureBinding (int textureIndex) const 902 { 903 DE_ASSERT(m_textureBindings.size() > (size_t)textureIndex); 904 return m_textureBindings[textureIndex].get(); 905 } 906 907 deUint32 TextureRenderer::getRenderWidth (void) const 908 { 909 return m_renderWidth; 910 } 911 912 deUint32 TextureRenderer::getRenderHeight (void) const 913 { 914 return m_renderHeight; 915 } 916 917 Move<VkDescriptorSet> TextureRenderer::makeDescriptorSet (const VkDescriptorPool descriptorPool, const VkDescriptorSetLayout setLayout) const 918 { 919 const DeviceInterface& vkd = m_context.getDeviceInterface(); 920 const VkDevice vkDevice = m_context.getDevice(); 921 922 const VkDescriptorSetAllocateInfo allocateParams = 923 { 924 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType 925 DE_NULL, // const void* pNext 926 descriptorPool, // VkDescriptorPool descriptorPool 927 1u, // deUint32 descriptorSetCount 928 &setLayout, // const VkDescriptorSetLayout* pSetLayouts 929 }; 930 return allocateDescriptorSet(vkd, vkDevice, &allocateParams); 931 } 932 933 void TextureRenderer::addImageTransitionBarrier(VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const 934 { 935 const DeviceInterface& vkd = m_context.getDeviceInterface(); 936 937 const VkImageSubresourceRange subResourcerange = 938 { 939 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 940 0, // deUint32 baseMipLevel; 941 1, // deUint32 levelCount; 942 0, // deUint32 baseArrayLayer; 943 1 // deUint32 layerCount; 944 }; 945 946 const VkImageMemoryBarrier imageBarrier = 947 { 948 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 949 DE_NULL, // const void* pNext; 950 srcAccessMask, // VkAccessFlags srcAccessMask; 951 dstAccessMask, // VkAccessFlags dstAccessMask; 952 oldLayout, // VkImageLayout oldLayout; 953 newLayout, // VkImageLayout newLayout; 954 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 955 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 956 image, // VkImage image; 957 subResourcerange // VkImageSubresourceRange subresourceRange; 958 }; 959 960 vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, 0, 0, DE_NULL, 0, DE_NULL, 1, &imageBarrier); 961 } 962 963 void TextureRenderer::renderQuad (tcu::Surface& result, int texUnit, const float* texCoord, TextureType texType) 964 { 965 renderQuad(result, texUnit, texCoord, ReferenceParams(texType)); 966 } 967 968 void TextureRenderer::renderQuad (tcu::Surface& result, int texUnit, const float* texCoord, const ReferenceParams& params) 969 { 970 const float maxAnisotropy = 1.0f; 971 float positions[] = 972 { 973 -1.0, -1.0f, 0.0f, 1.0f, 974 -1.0f, +1.0f, 0.0f, 1.0f, 975 +1.0f, -1.0f, 0.0f, 1.0f, 976 +1.0f, +1.0f, 0.0f, 1.0f 977 }; 978 renderQuad(result, positions, texUnit, texCoord, params, maxAnisotropy); 979 } 980 981 void TextureRenderer::renderQuad (tcu::Surface& result, 982 const float* positions, 983 int texUnit, 984 const float* texCoord, 985 const glu::TextureTestUtil::ReferenceParams& params, 986 const float maxAnisotropy) 987 { 988 const DeviceInterface& vkd = m_context.getDeviceInterface(); 989 const VkDevice vkDevice = m_context.getDevice(); 990 const VkQueue queue = m_context.getUniversalQueue(); 991 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 992 Allocator& allocator = m_context.getDefaultAllocator(); 993 994 tcu::Vec4 wCoord = params.flags & RenderParams::PROJECTED ? params.w : tcu::Vec4(1.0f); 995 bool useBias = !!(params.flags & RenderParams::USE_BIAS); 996 bool logUniforms = !!(params.flags & RenderParams::LOG_UNIFORMS); 997 998 // Render quad with texture. 999 float position[] = 1000 { 1001 positions[0]*wCoord.x(), positions[1]*wCoord.x(), positions[2], positions[3]*wCoord.x(), 1002 positions[4]*wCoord.y(), positions[5]*wCoord.y(), positions[6], positions[7]*wCoord.y(), 1003 positions[8]*wCoord.z(), positions[9]*wCoord.z(), positions[10], positions[11]*wCoord.z(), 1004 positions[12]*wCoord.w(), positions[13]*wCoord.w(), positions[14], positions[15]*wCoord.w() 1005 }; 1006 1007 Program progSpec = PROGRAM_LAST; 1008 int numComps = 0; 1009 1010 if (params.texType == TEXTURETYPE_2D) 1011 { 1012 numComps = 2; 1013 1014 switch (params.samplerType) 1015 { 1016 case SAMPLERTYPE_FLOAT: progSpec = useBias ? PROGRAM_2D_FLOAT_BIAS : PROGRAM_2D_FLOAT; break; 1017 case SAMPLERTYPE_INT: progSpec = useBias ? PROGRAM_2D_INT_BIAS : PROGRAM_2D_INT; break; 1018 case SAMPLERTYPE_UINT: progSpec = useBias ? PROGRAM_2D_UINT_BIAS : PROGRAM_2D_UINT; break; 1019 case SAMPLERTYPE_SHADOW: progSpec = useBias ? PROGRAM_2D_SHADOW_BIAS : PROGRAM_2D_SHADOW; break; 1020 default: DE_ASSERT(false); 1021 } 1022 } 1023 else if (params.texType == TEXTURETYPE_1D) 1024 { 1025 numComps = 1; 1026 1027 switch (params.samplerType) 1028 { 1029 case SAMPLERTYPE_FLOAT: progSpec = useBias ? PROGRAM_1D_FLOAT_BIAS : PROGRAM_1D_FLOAT; break; 1030 case SAMPLERTYPE_INT: progSpec = useBias ? PROGRAM_1D_INT_BIAS : PROGRAM_1D_INT; break; 1031 case SAMPLERTYPE_UINT: progSpec = useBias ? PROGRAM_1D_UINT_BIAS : PROGRAM_1D_UINT; break; 1032 case SAMPLERTYPE_SHADOW: progSpec = useBias ? PROGRAM_1D_SHADOW_BIAS : PROGRAM_1D_SHADOW; break; 1033 default: DE_ASSERT(false); 1034 } 1035 } 1036 else if (params.texType == TEXTURETYPE_CUBE) 1037 { 1038 numComps = 3; 1039 1040 switch (params.samplerType) 1041 { 1042 case SAMPLERTYPE_FLOAT: progSpec = useBias ? PROGRAM_CUBE_FLOAT_BIAS : PROGRAM_CUBE_FLOAT; break; 1043 case SAMPLERTYPE_INT: progSpec = useBias ? PROGRAM_CUBE_INT_BIAS : PROGRAM_CUBE_INT; break; 1044 case SAMPLERTYPE_UINT: progSpec = useBias ? PROGRAM_CUBE_UINT_BIAS : PROGRAM_CUBE_UINT; break; 1045 case SAMPLERTYPE_SHADOW: progSpec = useBias ? PROGRAM_CUBE_SHADOW_BIAS : PROGRAM_CUBE_SHADOW; break; 1046 default: DE_ASSERT(false); 1047 } 1048 } 1049 else if (params.texType == TEXTURETYPE_3D) 1050 { 1051 numComps = 3; 1052 1053 switch (params.samplerType) 1054 { 1055 case SAMPLERTYPE_FLOAT: progSpec = useBias ? PROGRAM_3D_FLOAT_BIAS : PROGRAM_3D_FLOAT; break; 1056 case SAMPLERTYPE_INT: progSpec = useBias ? PROGRAM_3D_INT_BIAS : PROGRAM_3D_INT; break; 1057 case SAMPLERTYPE_UINT: progSpec = useBias ? PROGRAM_3D_UINT_BIAS : PROGRAM_3D_UINT; break; 1058 default: DE_ASSERT(false); 1059 } 1060 } 1061 else if (params.texType == TEXTURETYPE_2D_ARRAY) 1062 { 1063 DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias. 1064 1065 numComps = 3; 1066 1067 switch (params.samplerType) 1068 { 1069 case SAMPLERTYPE_FLOAT: progSpec = PROGRAM_2D_ARRAY_FLOAT; break; 1070 case SAMPLERTYPE_INT: progSpec = PROGRAM_2D_ARRAY_INT; break; 1071 case SAMPLERTYPE_UINT: progSpec = PROGRAM_2D_ARRAY_UINT; break; 1072 case SAMPLERTYPE_SHADOW: progSpec = PROGRAM_2D_ARRAY_SHADOW; break; 1073 default: DE_ASSERT(false); 1074 } 1075 } 1076 else if (params.texType == TEXTURETYPE_CUBE_ARRAY) 1077 { 1078 DE_ASSERT(!useBias); 1079 1080 numComps = 4; 1081 1082 switch (params.samplerType) 1083 { 1084 case SAMPLERTYPE_FLOAT: progSpec = PROGRAM_CUBE_ARRAY_FLOAT; break; 1085 case SAMPLERTYPE_INT: progSpec = PROGRAM_CUBE_ARRAY_INT; break; 1086 case SAMPLERTYPE_UINT: progSpec = PROGRAM_CUBE_ARRAY_UINT; break; 1087 case SAMPLERTYPE_SHADOW: progSpec = PROGRAM_CUBE_ARRAY_SHADOW; break; 1088 default: DE_ASSERT(false); 1089 } 1090 } 1091 else if (params.texType == TEXTURETYPE_1D_ARRAY) 1092 { 1093 DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias. 1094 1095 numComps = 2; 1096 1097 switch (params.samplerType) 1098 { 1099 case SAMPLERTYPE_FLOAT: progSpec = PROGRAM_1D_ARRAY_FLOAT; break; 1100 case SAMPLERTYPE_INT: progSpec = PROGRAM_1D_ARRAY_INT; break; 1101 case SAMPLERTYPE_UINT: progSpec = PROGRAM_1D_ARRAY_UINT; break; 1102 case SAMPLERTYPE_SHADOW: progSpec = PROGRAM_1D_ARRAY_SHADOW; break; 1103 default: DE_ASSERT(false); 1104 } 1105 } 1106 else if (params.texType == TEXTURETYPE_BUFFER) 1107 { 1108 numComps = 1; 1109 1110 switch (params.samplerType) 1111 { 1112 case SAMPLERTYPE_FETCH_FLOAT: progSpec = PROGRAM_BUFFER_FLOAT; break; 1113 case SAMPLERTYPE_FETCH_INT: progSpec = PROGRAM_BUFFER_INT; break; 1114 case SAMPLERTYPE_FETCH_UINT: progSpec = PROGRAM_BUFFER_UINT; break; 1115 default: DE_ASSERT(false); 1116 } 1117 } 1118 else 1119 DE_ASSERT(DE_FALSE); 1120 1121 Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("vertext_" + std::string(getProgramName(progSpec))), 0)); 1122 Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("fragment_" + std::string(getProgramName(progSpec))), 0)); 1123 1124 Move<VkSampler> sampler; 1125 Move<VkDescriptorSet> descriptorSet[2]; 1126 Move<VkDescriptorSetLayout> descriptorSetLayout[2]; 1127 Move<VkPipelineLayout> pipelineLayout; 1128 1129 Move<VkCommandBuffer> commandBuffer; 1130 Move<VkPipeline> graphicsPipeline; 1131 Move<VkBuffer> vertexBuffer; 1132 de::MovePtr<Allocation> vertexBufferMemory; 1133 1134 const VkDeviceSize vertexBufferOffset = 0; 1135 const deUint32 vertexPositionStrideSize = deUint32(sizeof(tcu::Vec4)); 1136 const deUint32 vertexTextureStrideSize = deUint32(numComps * sizeof(float)); 1137 const deUint32 positionDataSize = vertexPositionStrideSize * 4u; 1138 const deUint32 textureCoordDataSize = vertexTextureStrideSize * 4u; 1139 1140 const VkPhysicalDeviceProperties properties = m_context.getDeviceProperties(); 1141 1142 if (positionDataSize > properties.limits.maxVertexInputAttributeOffset) 1143 { 1144 std::stringstream message; 1145 message << "Larger vertex input attribute offset is needed (" << positionDataSize << ") than the available maximum (" << properties.limits.maxVertexInputAttributeOffset << ")."; 1146 TCU_THROW(NotSupportedError, message.str().c_str()); 1147 } 1148 1149 // Create Graphics Pipeline 1150 { 1151 const VkVertexInputBindingDescription vertexInputBindingDescription[2] = 1152 { 1153 { 1154 0u, // deUint32 binding; 1155 vertexPositionStrideSize, // deUint32 strideInBytes; 1156 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate; 1157 }, 1158 { 1159 1u, // deUint32 binding; 1160 vertexTextureStrideSize, // deUint32 strideInBytes; 1161 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate; 1162 } 1163 }; 1164 1165 VkFormat textureCoordinateFormat = VK_FORMAT_R32G32B32A32_SFLOAT; 1166 1167 switch (numComps) { 1168 case 1: textureCoordinateFormat = VK_FORMAT_R32_SFLOAT; break; 1169 case 2: textureCoordinateFormat = VK_FORMAT_R32G32_SFLOAT; break; 1170 case 3: textureCoordinateFormat = VK_FORMAT_R32G32B32_SFLOAT; break; 1171 case 4: textureCoordinateFormat = VK_FORMAT_R32G32B32A32_SFLOAT; break; 1172 default: 1173 DE_ASSERT(false); 1174 } 1175 1176 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] = 1177 { 1178 { 1179 0u, // deUint32 location; 1180 0u, // deUint32 binding; 1181 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 1182 0u // deUint32 offsetInBytes; 1183 }, 1184 { 1185 1u, // deUint32 location; 1186 1u, // deUint32 binding; 1187 textureCoordinateFormat, // VkFormat format; 1188 positionDataSize // deUint32 offsetInBytes; 1189 } 1190 }; 1191 1192 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 1193 { 1194 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 1195 DE_NULL, // const void* pNext; 1196 0, // VkPipelineVertexInputStateCreateFlags flags; 1197 2u, // deUint32 bindingCount; 1198 vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 1199 2u, // deUint32 attributeCount; 1200 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 1201 }; 1202 1203 const VkViewport viewport = 1204 { 1205 m_viewportOffsetX, // float originX; 1206 m_viewportOffsetY, // float originY; 1207 m_viewportWidth, // float width; 1208 m_viewportHeight, // float height; 1209 0.0f, // float minDepth; 1210 1.0f // float maxDepth; 1211 }; 1212 const std::vector<VkViewport> viewports (1, viewport); 1213 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(m_renderWidth, m_renderHeight))); 1214 1215 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 1216 { 1217 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 1218 DE_NULL, // const void* pNext; 1219 0u, // VkPipelineMultisampleStateCreateFlags flags; 1220 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples; 1221 VK_FALSE, // VkBool32 sampleShadingEnable; 1222 0.0f, // float minSampleShading; 1223 DE_NULL, // const VkSampleMask* pSampleMask; 1224 VK_FALSE, // VkBool32 alphaToCoverageEnable; 1225 VK_FALSE // VkBool32 alphaToOneEnable; 1226 }; 1227 1228 VkSamplerCreateInfo samplerCreateInfo = mapSampler(params.sampler, m_textureBindings[texUnit]->getTestTexture().getTextureFormat(), params.minLod, params.maxLod, params.unnormal); 1229 1230 if (maxAnisotropy > 1.0f) 1231 { 1232 samplerCreateInfo.anisotropyEnable = VK_TRUE; 1233 samplerCreateInfo.maxAnisotropy = maxAnisotropy; 1234 } 1235 1236 if (samplerCreateInfo.magFilter == VK_FILTER_LINEAR || samplerCreateInfo.minFilter == VK_FILTER_LINEAR || samplerCreateInfo.mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR) 1237 { 1238 const pipeline::TestTexture& testTexture = m_textureBindings[texUnit]->getTestTexture(); 1239 const VkFormat textureFormat = testTexture.isCompressed() ? mapCompressedTextureFormat(testTexture.getCompressedLevel(0, 0).getFormat()) 1240 : mapTextureFormat (testTexture.getTextureFormat()); 1241 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), textureFormat); 1242 1243 if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) 1244 TCU_THROW(NotSupportedError, "Linear filtering for this image format is not supported"); 1245 } 1246 1247 sampler = createSampler(vkd, vkDevice, &samplerCreateInfo); 1248 1249 descriptorSetLayout[0] = DescriptorSetLayoutBuilder() 1250 .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT) 1251 .build(vkd, vkDevice); 1252 1253 descriptorSetLayout[1] = DescriptorSetLayoutBuilder() 1254 .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, &sampler.get()) 1255 .build(vkd, vkDevice); 1256 1257 descriptorSet[0] = makeDescriptorSet(*m_descriptorPool, *descriptorSetLayout[0]); 1258 descriptorSet[1] = makeDescriptorSet(*m_descriptorPool, *descriptorSetLayout[1]); 1259 1260 { 1261 const VkDescriptorBufferInfo descriptorBufferInfo = 1262 { 1263 *m_uniformBuffer, // VkBuffer buffer; 1264 0u, // VkDeviceSize offset; 1265 VK_WHOLE_SIZE // VkDeviceSize range; 1266 }; 1267 1268 DescriptorSetUpdateBuilder() 1269 .writeSingle(*descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &descriptorBufferInfo) 1270 .update(vkd, vkDevice); 1271 } 1272 1273 { 1274 VkDescriptorImageInfo descriptorImageInfo = 1275 { 1276 *sampler, // VkSampler sampler; 1277 m_textureBindings[texUnit]->getImageView(), // VkImageView imageView; 1278 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout imageLayout; 1279 }; 1280 1281 DescriptorSetUpdateBuilder() 1282 .writeSingle(*descriptorSet[1], DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfo) 1283 .update(vkd, vkDevice); 1284 } 1285 1286 // Pipeline Layout 1287 { 1288 VkDescriptorSetLayout descriptorSetLayouts[2] = 1289 { 1290 *descriptorSetLayout[0], 1291 *descriptorSetLayout[1] 1292 }; 1293 1294 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = 1295 { 1296 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 1297 DE_NULL, // const void* pNext; 1298 0u, // VkPipelineLayoutCreateFlags flags; 1299 2u, // deUint32 descriptorSetCount; 1300 descriptorSetLayouts, // const VkDescriptorSetLayout* pSetLayouts; 1301 0u, // deUint32 pushConstantRangeCount; 1302 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 1303 }; 1304 1305 pipelineLayout = createPipelineLayout(vkd, vkDevice, &pipelineLayoutCreateInfo); 1306 } 1307 1308 graphicsPipeline = makeGraphicsPipeline(vkd, // const DeviceInterface& vk 1309 vkDevice, // const VkDevice device 1310 *pipelineLayout, // const VkPipelineLayout pipelineLayout 1311 *vertexShaderModule, // const VkShaderModule vertexShaderModule 1312 DE_NULL, // const VkShaderModule tessellationControlShaderModule 1313 DE_NULL, // const VkShaderModule tessellationEvalShaderModule 1314 DE_NULL, // const VkShaderModule geometryShaderModule 1315 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule 1316 *m_renderPass, // const VkRenderPass renderPass 1317 viewports, // const std::vector<VkViewport>& viewports 1318 scissors, // const std::vector<VkRect2D>& scissors 1319 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology 1320 0u, // const deUint32 subpass 1321 0u, // const deUint32 patchControlPoints 1322 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo 1323 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo 1324 &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo 1325 } 1326 1327 // Create Vertex Buffer 1328 { 1329 VkDeviceSize bufferSize = positionDataSize + textureCoordDataSize; 1330 1331 // Pad the buffer size to a stride multiple for the last element so that it isn't out of bounds 1332 bufferSize += vertexTextureStrideSize - ((bufferSize - vertexBufferOffset) % vertexTextureStrideSize); 1333 1334 const VkBufferCreateInfo vertexBufferParams = 1335 { 1336 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1337 DE_NULL, // const void* pNext; 1338 0u, // VkBufferCreateFlags flags; 1339 bufferSize, // VkDeviceSize size; 1340 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; 1341 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1342 1u, // deUint32 queueFamilyCount; 1343 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 1344 }; 1345 1346 vertexBuffer = createBuffer(vkd, vkDevice, &vertexBufferParams); 1347 vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible); 1348 1349 VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset())); 1350 1351 // Load vertices into vertex buffer 1352 deMemcpy(vertexBufferMemory->getHostPtr(), position, positionDataSize); 1353 deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) + positionDataSize, texCoord, textureCoordDataSize); 1354 flushMappedMemoryRange(vkd, vkDevice, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset(), VK_WHOLE_SIZE); 1355 } 1356 1357 // Create Command Buffer 1358 commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 1359 1360 // Begin Command Buffer 1361 beginCommandBuffer(vkd, *commandBuffer); 1362 1363 // Begin Render Pass 1364 beginRenderPass(vkd, *commandBuffer, *m_renderPass, *m_frameBuffer, makeRect2D(0, 0, m_renderWidth, m_renderHeight)); 1365 1366 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline); 1367 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1, &descriptorSet[0].get(), 0u, DE_NULL); 1368 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 1u, 1, &descriptorSet[1].get(), 0u, DE_NULL); 1369 vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset); 1370 vkd.cmdBindVertexBuffers(*commandBuffer, 1, 1, &vertexBuffer.get(), &vertexBufferOffset); 1371 vkd.cmdBindIndexBuffer(*commandBuffer, *m_vertexIndexBuffer, 0, VK_INDEX_TYPE_UINT16); 1372 vkd.cmdDrawIndexed(*commandBuffer, 6, 1, 0, 0, 0); 1373 endRenderPass(vkd, *commandBuffer); 1374 1375 // Copy Image 1376 { 1377 copyImageToBuffer(vkd, *commandBuffer, m_multisampling ? *m_resolvedImage : *m_image, *m_resultBuffer, tcu::IVec2(m_renderWidth, m_renderHeight)); 1378 1379 addImageTransitionBarrier(*commandBuffer, 1380 m_multisampling ? *m_resolvedImage : *m_image, 1381 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags srcStageMask 1382 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags dstStageMask 1383 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask 1384 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask 1385 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout oldLayout; 1386 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout; 1387 } 1388 1389 endCommandBuffer(vkd, *commandBuffer); 1390 1391 // Upload uniform buffer data 1392 { 1393 const ShaderParameters shaderParameters = 1394 { 1395 params.bias, // float bias; //!< User-supplied bias. 1396 params.ref, // float ref; //!< Reference value for shadow lookups. 1397 tcu::Vec2(), // tcu::Vec2 padding; //!< Shader uniform padding. 1398 params.colorScale, // tcu::Vec4 colorScale; //!< Scale for texture color values. 1399 params.colorBias // tcu::Vec4 colorBias; //!< Bias for texture color values. 1400 }; 1401 deMemcpy(m_uniformBufferMemory->getHostPtr(), &shaderParameters, sizeof(shaderParameters)); 1402 flushMappedMemoryRange(vkd, vkDevice, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset(), VK_WHOLE_SIZE); 1403 1404 if (logUniforms) 1405 m_log << TestLog::Message << "u_sampler = " << texUnit << TestLog::EndMessage; 1406 1407 if (useBias) 1408 { 1409 if (logUniforms) 1410 m_log << TestLog::Message << "u_bias = " << shaderParameters.bias << TestLog::EndMessage; 1411 } 1412 1413 if (params.samplerType == SAMPLERTYPE_SHADOW) 1414 { 1415 if (logUniforms) 1416 m_log << TestLog::Message << "u_ref = " << shaderParameters.ref << TestLog::EndMessage; 1417 } 1418 1419 if (logUniforms) 1420 { 1421 m_log << TestLog::Message << "u_colorScale = " << shaderParameters.colorScale << TestLog::EndMessage; 1422 m_log << TestLog::Message << "u_colorBias = " << shaderParameters.colorBias << TestLog::EndMessage; 1423 } 1424 } 1425 1426 // Submit 1427 submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get()); 1428 1429 invalidateMappedMemoryRange(vkd, vkDevice, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset(), VK_WHOLE_SIZE); 1430 1431 tcu::copy(result.getAccess(), tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderWidth, m_renderHeight, 1u), m_resultBufferMemory->getHostPtr())); 1432 } 1433 1434 /*--------------------------------------------------------------------*//*! 1435 * \brief Map Vulkan sampler parameters to tcu::Sampler. 1436 * 1437 * If no mapping is found, throws tcu::InternalError. 1438 * 1439 * \param wrapU U-component wrap mode 1440 * \param wrapV V-component wrap mode 1441 * \param wrapW W-component wrap mode 1442 * \param minFilterMode Minification filter mode 1443 * \param magFilterMode Magnification filter mode 1444 * \return Sampler description. 1445 *//*--------------------------------------------------------------------*/ 1446 tcu::Sampler createSampler (tcu::Sampler::WrapMode wrapU, tcu::Sampler::WrapMode wrapV, tcu::Sampler::WrapMode wrapW, tcu::Sampler::FilterMode minFilterMode, tcu::Sampler::FilterMode magFilterMode, bool normalizedCoords) 1447 { 1448 return tcu::Sampler(wrapU, wrapV, wrapW, 1449 minFilterMode, magFilterMode, 1450 0.0f /* lod threshold */, 1451 normalizedCoords /* normalized coords */, 1452 tcu::Sampler::COMPAREMODE_NONE /* no compare */, 1453 0 /* compare channel */, 1454 tcu::Vec4(0.0f) /* border color, not used */); 1455 } 1456 1457 /*--------------------------------------------------------------------*//*! 1458 * \brief Map Vulkan sampler parameters to tcu::Sampler. 1459 * 1460 * If no mapping is found, throws tcu::InternalError. 1461 * 1462 * \param wrapU U-component wrap mode 1463 * \param wrapV V-component wrap mode 1464 * \param minFilterMode Minification filter mode 1465 * \param minFilterMode Magnification filter mode 1466 * \return Sampler description. 1467 *//*--------------------------------------------------------------------*/ 1468 tcu::Sampler createSampler (tcu::Sampler::WrapMode wrapU, tcu::Sampler::WrapMode wrapV, tcu::Sampler::FilterMode minFilterMode, tcu::Sampler::FilterMode magFilterMode, bool normalizedCoords) 1469 { 1470 return createSampler(wrapU, wrapV, wrapU, minFilterMode, magFilterMode, normalizedCoords); 1471 } 1472 1473 /*--------------------------------------------------------------------*//*! 1474 * \brief Map Vulkan sampler parameters to tcu::Sampler. 1475 * 1476 * If no mapping is found, throws tcu::InternalError. 1477 * 1478 * \param wrapU U-component wrap mode 1479 * \param minFilterMode Minification filter mode 1480 * \return Sampler description. 1481 *//*--------------------------------------------------------------------*/ 1482 tcu::Sampler createSampler (tcu::Sampler::WrapMode wrapU, tcu::Sampler::FilterMode minFilterMode, tcu::Sampler::FilterMode magFilterMode, bool normalizedCoords) 1483 { 1484 return createSampler(wrapU, wrapU, wrapU, minFilterMode, magFilterMode, normalizedCoords); 1485 } 1486 1487 TestTexture2DSp loadTexture2D (const tcu::Archive& archive, const std::vector<std::string>& filenames) 1488 { 1489 DE_ASSERT(filenames.size() > 0); 1490 1491 TestTexture2DSp texture; 1492 1493 std::string ext = de::FilePath(filenames[0]).getFileExtension(); 1494 1495 if (ext == "png") 1496 { 1497 1498 for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex) 1499 { 1500 tcu::TextureLevel level; 1501 1502 tcu::ImageIO::loadImage(level, archive, filenames[fileIndex].c_str()); 1503 1504 TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) || 1505 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8)); 1506 1507 if (fileIndex == 0) 1508 texture = TestTexture2DSp(new pipeline::TestTexture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(), level.getHeight())); 1509 1510 tcu::copy(texture->getLevel((int)fileIndex, 0), level.getAccess()); 1511 } 1512 } 1513 else if (ext == "pkm") 1514 { 1515 1516 for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex) 1517 { 1518 // Compressed texture. 1519 tcu::CompressedTexture level; 1520 1521 tcu::ImageIO::loadPKM(level, archive, filenames[fileIndex].c_str()); 1522 1523 tcu::TextureFormat uncompressedFormat = tcu::getUncompressedFormat(level.getFormat()); 1524 std::vector<deUint8> uncompressedData (uncompressedFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0); 1525 tcu::PixelBufferAccess decompressedBuffer (uncompressedFormat, level.getWidth(), level.getHeight(), 1, uncompressedData.data()); 1526 1527 tcu::TextureFormat commonFormat = tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8); 1528 std::vector<deUint8> commonFromatData (commonFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0); 1529 tcu::PixelBufferAccess commonFormatBuffer (commonFormat, level.getWidth(), level.getHeight(), 1, commonFromatData.data()); 1530 1531 if (fileIndex == 0) 1532 texture = TestTexture2DSp(new pipeline::TestTexture2D(commonFormat, level.getWidth(), level.getHeight())); 1533 1534 level.decompress(decompressedBuffer, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR)); 1535 1536 tcu::copy(commonFormatBuffer, decompressedBuffer); 1537 tcu::copy(texture->getLevel((int)fileIndex, 0), commonFormatBuffer); 1538 } 1539 } 1540 else 1541 TCU_FAIL("Unsupported file format"); 1542 1543 return texture; 1544 } 1545 1546 TestTextureCubeSp loadTextureCube (const tcu::Archive& archive, const std::vector<std::string>& filenames) 1547 { 1548 DE_ASSERT(filenames.size() > 0); 1549 DE_STATIC_ASSERT(tcu::CUBEFACE_LAST == 6); 1550 TCU_CHECK((int)filenames.size() % tcu::CUBEFACE_LAST == 0); 1551 1552 TestTextureCubeSp texture; 1553 1554 std::string ext = de::FilePath(filenames[0]).getFileExtension(); 1555 1556 if (ext == "png") 1557 { 1558 1559 for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex) 1560 { 1561 tcu::TextureLevel level; 1562 1563 tcu::ImageIO::loadImage(level, archive, filenames[fileIndex].c_str()); 1564 1565 TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) || 1566 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8)); 1567 1568 TCU_CHECK( level.getWidth() == level.getHeight()); 1569 1570 if (fileIndex == 0) 1571 texture = TestTextureCubeSp(new pipeline::TestTextureCube(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth())); 1572 1573 tcu::copy(texture->getLevel((int)fileIndex / 6, (int)fileIndex % 6), level.getAccess()); 1574 } 1575 } 1576 else if (ext == "pkm") 1577 { 1578 for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex) 1579 { 1580 // Compressed texture. 1581 tcu::CompressedTexture level; 1582 1583 tcu::ImageIO::loadPKM(level, archive, filenames[fileIndex].c_str()); 1584 1585 TCU_CHECK( level.getWidth() == level.getHeight()); 1586 1587 tcu::TextureFormat uncompressedFormat = tcu::getUncompressedFormat(level.getFormat()); 1588 std::vector<deUint8> uncompressedData (uncompressedFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0); 1589 tcu::PixelBufferAccess decompressedBuffer (uncompressedFormat, level.getWidth(), level.getHeight(), 1, uncompressedData.data()); 1590 1591 tcu::TextureFormat commonFormat = tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8); 1592 std::vector<deUint8> commonFromatData (commonFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0); 1593 tcu::PixelBufferAccess commonFormatBuffer (commonFormat, level.getWidth(), level.getHeight(), 1, commonFromatData.data()); 1594 1595 if (fileIndex == 0) 1596 texture = TestTextureCubeSp(new pipeline::TestTextureCube(commonFormat, level.getWidth())); 1597 1598 level.decompress(decompressedBuffer, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR)); 1599 1600 tcu::copy(commonFormatBuffer, decompressedBuffer); 1601 tcu::copy(texture->getLevel((int)fileIndex / 6, (int)fileIndex % 6), commonFormatBuffer); 1602 } 1603 } 1604 else 1605 TCU_FAIL("Unsupported file format"); 1606 1607 return texture; 1608 } 1609 1610 TextureCommonTestCaseParameters::TextureCommonTestCaseParameters (void) 1611 : sampleCount (VK_SAMPLE_COUNT_1_BIT) 1612 , texCoordPrecision (glu::PRECISION_HIGHP) 1613 , minFilter (tcu::Sampler::LINEAR) 1614 , magFilter (tcu::Sampler::LINEAR) 1615 , wrapS (tcu::Sampler::REPEAT_GL) 1616 , wrapT (tcu::Sampler::REPEAT_GL) 1617 , format (VK_FORMAT_R8G8B8A8_UNORM) 1618 , unnormal (false) 1619 { 1620 } 1621 1622 Texture2DTestCaseParameters::Texture2DTestCaseParameters (void) 1623 : width (64) 1624 , height (64) 1625 { 1626 } 1627 1628 TextureCubeTestCaseParameters::TextureCubeTestCaseParameters (void) 1629 : size (64) 1630 { 1631 } 1632 1633 Texture2DArrayTestCaseParameters::Texture2DArrayTestCaseParameters (void) 1634 : numLayers (8) 1635 { 1636 } 1637 1638 Texture3DTestCaseParameters::Texture3DTestCaseParameters (void) 1639 : wrapR (tcu::Sampler::REPEAT_GL) 1640 , depth (64) 1641 { 1642 } 1643 1644 } // util 1645 } // texture 1646 } // vkt 1647