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