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 = 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 = 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 const deUint32 positionDataSize = deUint32(sizeof(float) * 4 * 4); 1110 const deUint32 textureCoordDataSize = deUint32(sizeof(float) * numComps * 4); 1111 1112 const VkPhysicalDeviceProperties properties = m_context.getDeviceProperties(); 1113 1114 if (positionDataSize > properties.limits.maxVertexInputAttributeOffset) 1115 { 1116 std::stringstream message; 1117 message << "Larger vertex input attribute offset is needed (" << positionDataSize << ") than the available maximum (" << properties.limits.maxVertexInputAttributeOffset << ")."; 1118 TCU_THROW(NotSupportedError, message.str().c_str()); 1119 } 1120 1121 // Create Graphics Pipeline 1122 { 1123 const VkPipelineShaderStageCreateInfo shaderStageParams[2] = 1124 { 1125 { 1126 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 1127 DE_NULL, // const void* pNext; 1128 0, // VkPipelineShaderStageCreateFlags flags; 1129 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStage stage; 1130 *vertexShaderModule, // VkShaderModule shader; 1131 "main", // const char* pName; 1132 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 1133 }, 1134 { 1135 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 1136 DE_NULL, // const void* pNext; 1137 0, // VkPipelineShaderStageCreateFlags flags; 1138 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStage stage; 1139 *fragmentShaderModule, // VkShaderModule shader; 1140 "main", // const char* pName; 1141 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 1142 } 1143 }; 1144 1145 const deUint32 vertexPositionStrideSize = deUint32(sizeof(tcu::Vec4)); 1146 const deUint32 vertexTextureStrideSize = deUint32(numComps * sizeof(float)); 1147 1148 const VkVertexInputBindingDescription vertexInputBindingDescription[2] = 1149 { 1150 { 1151 0u, // deUint32 binding; 1152 vertexPositionStrideSize, // deUint32 strideInBytes; 1153 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate; 1154 }, 1155 { 1156 1u, // deUint32 binding; 1157 vertexTextureStrideSize, // deUint32 strideInBytes; 1158 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate; 1159 } 1160 }; 1161 1162 VkFormat textureCoordinateFormat = VK_FORMAT_R32G32B32A32_SFLOAT; 1163 1164 switch (numComps) { 1165 case 1: textureCoordinateFormat = VK_FORMAT_R32_SFLOAT; break; 1166 case 2: textureCoordinateFormat = VK_FORMAT_R32G32_SFLOAT; break; 1167 case 3: textureCoordinateFormat = VK_FORMAT_R32G32B32_SFLOAT; break; 1168 case 4: textureCoordinateFormat = VK_FORMAT_R32G32B32A32_SFLOAT; break; 1169 default: 1170 DE_ASSERT(false); 1171 } 1172 1173 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] = 1174 { 1175 { 1176 0u, // deUint32 location; 1177 0u, // deUint32 binding; 1178 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 1179 0u // deUint32 offsetInBytes; 1180 }, 1181 { 1182 1u, // deUint32 location; 1183 1u, // deUint32 binding; 1184 textureCoordinateFormat, // VkFormat format; 1185 positionDataSize // deUint32 offsetInBytes; 1186 } 1187 }; 1188 1189 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 1190 { 1191 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 1192 DE_NULL, // const void* pNext; 1193 0, // VkPipelineVertexInputStateCreateFlags flags; 1194 2u, // deUint32 bindingCount; 1195 vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 1196 2u, // deUint32 attributeCount; 1197 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 1198 }; 1199 1200 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = 1201 { 1202 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 1203 DE_NULL, // const void* pNext; 1204 0, // VkPipelineInputAssemblyStateCreateFlags flags; 1205 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology; 1206 VK_FALSE // VkBool32 primitiveRestartEnable; 1207 }; 1208 1209 const VkViewport viewport = 1210 { 1211 m_viewportOffsetX, // float originX; 1212 m_viewportOffsetY, // float originY; 1213 m_viewportWidth, // float width; 1214 m_viewportHeight, // float height; 1215 0.0f, // float minDepth; 1216 1.0f // float maxDepth; 1217 }; 1218 1219 const VkRect2D scissor = 1220 { 1221 { 0, 0 }, // VkOffset2D offset; 1222 { m_renderWidth, m_renderHeight } // VkExtent2D extent; 1223 }; 1224 1225 const VkPipelineViewportStateCreateInfo viewportStateParams = 1226 { 1227 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 1228 DE_NULL, // const void* pNext; 1229 0, // VkPipelineViewportStateCreateFlags flags; 1230 1u, // deUint32 viewportCount; 1231 &viewport, // const VkViewport* pViewports; 1232 1u, // deUint32 scissorCount; 1233 &scissor // const VkRect2D* pScissors; 1234 }; 1235 1236 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 1237 { 1238 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 1239 DE_NULL, // const void* pNext; 1240 0u, // VkPipelineMultisampleStateCreateFlags flags; 1241 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples; 1242 VK_FALSE, // VkBool32 sampleShadingEnable; 1243 0.0f, // float minSampleShading; 1244 DE_NULL, // const VkSampleMask* pSampleMask; 1245 VK_FALSE, // VkBool32 alphaToCoverageEnable; 1246 VK_FALSE // VkBool32 alphaToOneEnable; 1247 }; 1248 1249 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo = 1250 { 1251 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 1252 DE_NULL, // const void* pNext; 1253 0, // VkPipelineRasterizationStateCreateFlags flags; 1254 VK_FALSE, // VkBool32 depthClipEnable; 1255 VK_FALSE, // VkBool32 rasterizerDiscardEnable; 1256 VK_POLYGON_MODE_FILL, // VkFillMode fillMode; 1257 VK_CULL_MODE_NONE, // VkCullMode cullMode; 1258 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 1259 VK_FALSE, // VkBool32 depthBiasEnable; 1260 0.0f, // float depthBias; 1261 0.0f, // float depthBiasClamp; 1262 0.0f, // float slopeScaledDepthBias; 1263 1.0f, // float lineWidth; 1264 }; 1265 1266 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = 1267 { 1268 VK_FALSE, // VkBool32 blendEnable; 1269 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor; 1270 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor; 1271 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor; 1272 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha; 1273 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha; 1274 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha; 1275 (VK_COLOR_COMPONENT_R_BIT | 1276 VK_COLOR_COMPONENT_G_BIT | 1277 VK_COLOR_COMPONENT_B_BIT | 1278 VK_COLOR_COMPONENT_A_BIT) // VkChannelFlags channelWriteMask; 1279 }; 1280 1281 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 1282 { 1283 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 1284 DE_NULL, // const void* pNext; 1285 0, // VkPipelineColorBlendStateCreateFlags flags; 1286 VK_FALSE, // VkBool32 logicOpEnable; 1287 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 1288 1u, // deUint32 attachmentCount; 1289 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 1290 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4]; 1291 }; 1292 1293 VkSamplerCreateInfo samplerCreateInfo = mapSampler(params.sampler, m_textureBindings[texUnit]->getTestTexture().getTextureFormat(), params.minLod, params.maxLod); 1294 1295 if (maxAnisotropy > 1.0f) 1296 { 1297 samplerCreateInfo.anisotropyEnable = VK_TRUE; 1298 samplerCreateInfo.maxAnisotropy = maxAnisotropy; 1299 } 1300 1301 if (samplerCreateInfo.magFilter == VK_FILTER_LINEAR || samplerCreateInfo.minFilter == VK_FILTER_LINEAR || samplerCreateInfo.mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR) 1302 { 1303 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), mapTextureFormat(m_textureBindings[texUnit]->getTestTexture().getTextureFormat())); 1304 if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) 1305 TCU_THROW(NotSupportedError, "Linear filtering for this image format is not supported"); 1306 } 1307 1308 sampler = createSampler(vkd, vkDevice, &samplerCreateInfo); 1309 1310 descriptorSetLayout[0] = DescriptorSetLayoutBuilder() 1311 .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT) 1312 .build(vkd, vkDevice); 1313 1314 descriptorSetLayout[1] = DescriptorSetLayoutBuilder() 1315 .addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, &sampler.get()) 1316 .build(vkd, vkDevice); 1317 1318 1319 descriptorSet[0] = makeDescriptorSet(*m_descriptorPool, *descriptorSetLayout[0]); 1320 descriptorSet[1] = makeDescriptorSet(*m_descriptorPool, *descriptorSetLayout[1]); 1321 1322 { 1323 const VkDescriptorBufferInfo descriptorBufferInfo = 1324 { 1325 *m_uniformBuffer, // VkBuffer buffer; 1326 0u, // VkDeviceSize offset; 1327 VK_WHOLE_SIZE // VkDeviceSize range; 1328 }; 1329 1330 DescriptorSetUpdateBuilder() 1331 .writeSingle(*descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &descriptorBufferInfo) 1332 .update(vkd, vkDevice); 1333 } 1334 1335 { 1336 VkDescriptorImageInfo descriptorImageInfo = 1337 { 1338 *sampler, // VkSampler sampler; 1339 m_textureBindings[texUnit]->getImageView(), // VkImageView imageView; 1340 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout imageLayout; 1341 }; 1342 1343 DescriptorSetUpdateBuilder() 1344 .writeSingle(*descriptorSet[1], DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfo) 1345 .update(vkd, vkDevice); 1346 } 1347 1348 // Pipeline Layout 1349 { 1350 VkDescriptorSetLayout descriptorSetLayouts[2] = 1351 { 1352 *descriptorSetLayout[0], 1353 *descriptorSetLayout[1] 1354 }; 1355 1356 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = 1357 { 1358 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 1359 DE_NULL, // const void* pNext; 1360 0u, // VkPipelineLayoutCreateFlags flags; 1361 2u, // deUint32 descriptorSetCount; 1362 descriptorSetLayouts, // const VkDescriptorSetLayout* pSetLayouts; 1363 0u, // deUint32 pushConstantRangeCount; 1364 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 1365 }; 1366 1367 pipelineLayout = createPipelineLayout(vkd, vkDevice, &pipelineLayoutCreateInfo); 1368 } 1369 1370 const VkGraphicsPipelineCreateInfo graphicsPipelineParams = 1371 { 1372 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 1373 DE_NULL, // const void* pNext; 1374 0u, // VkPipelineCreateFlags flags; 1375 2u, // deUint32 stageCount; 1376 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages; 1377 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 1378 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 1379 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 1380 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; 1381 &rasterizationStateCreateInfo, // const VkPipelineRasterStateCreateInfo* pRasterizationState; 1382 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 1383 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 1384 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 1385 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 1386 *pipelineLayout, // VkPipelineLayout layout; 1387 *m_renderPass, // VkRenderPass renderPass; 1388 0u, // deUint32 subpass; 1389 0u, // VkPipeline basePipelineHandle; 1390 0u // deInt32 basePipelineIndex; 1391 }; 1392 1393 graphicsPipeline = createGraphicsPipeline(vkd, vkDevice, DE_NULL, &graphicsPipelineParams); 1394 } 1395 1396 // Create Vertex Buffer 1397 { 1398 const VkBufferCreateInfo vertexBufferParams = 1399 { 1400 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1401 DE_NULL, // const void* pNext; 1402 0u, // VkBufferCreateFlags flags; 1403 positionDataSize + textureCoordDataSize, // VkDeviceSize size; 1404 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; 1405 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1406 1u, // deUint32 queueFamilyCount; 1407 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 1408 }; 1409 1410 vertexBuffer = createBuffer(vkd, vkDevice, &vertexBufferParams); 1411 vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible); 1412 1413 VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset())); 1414 1415 // Load vertices into vertex buffer 1416 deMemcpy(vertexBufferMemory->getHostPtr(), position, positionDataSize); 1417 deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) + positionDataSize, texCoord, textureCoordDataSize); 1418 flushMappedMemoryRange(vkd, vkDevice, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset(), VK_WHOLE_SIZE); 1419 } 1420 1421 // Create Command Buffer 1422 commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 1423 1424 // Begin Command Buffer 1425 { 1426 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1427 { 1428 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1429 DE_NULL, // const void* pNext; 1430 0u, // VkCmdBufferOptimizeFlags flags; 1431 DE_NULL // const VkCommandBufferInheritanceInfo* pInheritanceInfo; 1432 }; 1433 1434 VK_CHECK(vkd.beginCommandBuffer(*commandBuffer, &cmdBufferBeginInfo)); 1435 } 1436 1437 // Begin Render Pass 1438 { 1439 const VkRenderPassBeginInfo renderPassBeginInfo = 1440 { 1441 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 1442 DE_NULL, // const void* pNext; 1443 *m_renderPass, // VkRenderPass renderPass; 1444 *m_frameBuffer, // VkFramebuffer framebuffer; 1445 { 1446 { 0, 0 }, 1447 { m_renderWidth, m_renderHeight } 1448 }, // VkRect2D renderArea; 1449 0u, // deUint32 clearValueCount; 1450 DE_NULL // const VkClearValue* pClearValues; 1451 }; 1452 1453 vkd.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 1454 } 1455 1456 const VkDeviceSize vertexBufferOffset = 0; 1457 1458 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline); 1459 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1, &descriptorSet[0].get(), 0u, DE_NULL); 1460 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 1u, 1, &descriptorSet[1].get(), 0u, DE_NULL); 1461 vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset); 1462 vkd.cmdBindVertexBuffers(*commandBuffer, 1, 1, &vertexBuffer.get(), &vertexBufferOffset); 1463 vkd.cmdBindIndexBuffer(*commandBuffer, *m_vertexIndexBuffer, 0, VK_INDEX_TYPE_UINT16); 1464 vkd.cmdDrawIndexed(*commandBuffer, 6, 1, 0, 0, 0); 1465 vkd.cmdEndRenderPass(*commandBuffer); 1466 1467 // Copy Image 1468 { 1469 const VkBufferMemoryBarrier bufferBarrier = 1470 { 1471 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1472 DE_NULL, // const void* pNext; 1473 VK_ACCESS_TRANSFER_WRITE_BIT, // VkMemoryOutputFlags outputMask; 1474 VK_ACCESS_HOST_READ_BIT, // VkMemoryInputFlags inputMask; 1475 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1476 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 1477 *m_resultBuffer, // VkBuffer buffer; 1478 0u, // VkDeviceSize offset; 1479 m_resultBufferSize // VkDeviceSize size; 1480 }; 1481 1482 const VkBufferImageCopy copyRegion = 1483 { 1484 0u, // VkDeviceSize bufferOffset; 1485 m_renderWidth, // deUint32 bufferRowLength; 1486 m_renderHeight, // deUint32 bufferImageHeight; 1487 { 1488 VK_IMAGE_ASPECT_COLOR_BIT, 1489 0u, 1490 0u, 1491 1u 1492 }, // VkImageSubresourceCopy imageSubresource; 1493 { 0, 0, 0 }, // VkOffset3D imageOffset; 1494 { m_renderWidth, m_renderHeight, 1u } // VkExtent3D imageExtent; 1495 }; 1496 1497 addImageTransitionBarrier(*commandBuffer, 1498 m_multisampling ? *m_resolvedImage : *m_image, 1499 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask 1500 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask 1501 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask 1502 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask 1503 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout; 1504 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); // VkImageLayout newLayout; 1505 1506 if (m_multisampling) 1507 vkd.cmdCopyImageToBuffer(*commandBuffer, *m_resolvedImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_resultBuffer, 1, ©Region); 1508 else 1509 vkd.cmdCopyImageToBuffer(*commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_resultBuffer, 1, ©Region); 1510 1511 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); 1512 1513 addImageTransitionBarrier(*commandBuffer, 1514 m_multisampling ? *m_resolvedImage : *m_image, 1515 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags srcStageMask 1516 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags dstStageMask 1517 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask 1518 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask 1519 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout oldLayout; 1520 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout; 1521 } 1522 1523 VK_CHECK(vkd.endCommandBuffer(*commandBuffer)); 1524 1525 // Upload uniform buffer data 1526 { 1527 const ShaderParameters shaderParameters = 1528 { 1529 params.bias, // float bias; //!< User-supplied bias. 1530 params.ref, // float ref; //!< Reference value for shadow lookups. 1531 tcu::Vec2(), // tcu::Vec2 padding; //!< Shader uniform padding. 1532 params.colorScale, // tcu::Vec4 colorScale; //!< Scale for texture color values. 1533 params.colorBias // tcu::Vec4 colorBias; //!< Bias for texture color values. 1534 }; 1535 deMemcpy(m_uniformBufferMemory->getHostPtr(), &shaderParameters, sizeof(shaderParameters)); 1536 flushMappedMemoryRange(vkd, vkDevice, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset(), VK_WHOLE_SIZE); 1537 1538 if (logUniforms) 1539 m_log << TestLog::Message << "u_sampler = " << texUnit << TestLog::EndMessage; 1540 1541 if (useBias) 1542 { 1543 if (logUniforms) 1544 m_log << TestLog::Message << "u_bias = " << shaderParameters.bias << TestLog::EndMessage; 1545 } 1546 1547 if (params.samplerType == SAMPLERTYPE_SHADOW) 1548 { 1549 if (logUniforms) 1550 m_log << TestLog::Message << "u_ref = " << shaderParameters.ref << TestLog::EndMessage; 1551 } 1552 1553 if (logUniforms) 1554 { 1555 m_log << TestLog::Message << "u_colorScale = " << shaderParameters.colorScale << TestLog::EndMessage; 1556 m_log << TestLog::Message << "u_colorBias = " << shaderParameters.colorBias << TestLog::EndMessage; 1557 } 1558 } 1559 1560 // Submit 1561 { 1562 const VkSubmitInfo submitInfo = 1563 { 1564 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 1565 DE_NULL, // const void* pNext; 1566 0u, // deUint32 waitSemaphoreCount; 1567 DE_NULL, // const VkSemaphore* pWaitSemaphores; 1568 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; 1569 1u, // deUint32 commandBufferCount; 1570 &commandBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 1571 0u, // deUint32 signalSemaphoreCount; 1572 DE_NULL, // const VkSemaphore* pSignalSemaphores; 1573 }; 1574 1575 VK_CHECK(vkd.resetFences(vkDevice, 1, &m_fence.get())); 1576 VK_CHECK(vkd.queueSubmit(queue, 1, &submitInfo, *m_fence)); 1577 VK_CHECK(vkd.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */)); 1578 } 1579 1580 invalidateMappedMemoryRange(vkd, vkDevice, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset(), VK_WHOLE_SIZE); 1581 1582 tcu::copy(result.getAccess(), tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderWidth, m_renderHeight, 1u), m_resultBufferMemory->getHostPtr())); 1583 } 1584 1585 /*--------------------------------------------------------------------*//*! 1586 * \brief Map Vulkan sampler parameters to tcu::Sampler. 1587 * 1588 * If no mapping is found, throws tcu::InternalError. 1589 * 1590 * \param wrapU U-component wrap mode 1591 * \param wrapV V-component wrap mode 1592 * \param wrapW W-component wrap mode 1593 * \param minFilterMode Minification filter mode 1594 * \param magFilterMode Magnification filter mode 1595 * \return Sampler description. 1596 *//*--------------------------------------------------------------------*/ 1597 tcu::Sampler createSampler (tcu::Sampler::WrapMode wrapU, tcu::Sampler::WrapMode wrapV, tcu::Sampler::WrapMode wrapW, tcu::Sampler::FilterMode minFilterMode, tcu::Sampler::FilterMode magFilterMode) 1598 { 1599 return tcu::Sampler(wrapU, wrapV, wrapW, 1600 minFilterMode, magFilterMode, 1601 0.0f /* lod threshold */, 1602 true /* normalized coords */, 1603 tcu::Sampler::COMPAREMODE_NONE /* no compare */, 1604 0 /* compare channel */, 1605 tcu::Vec4(0.0f) /* border color, not used */); 1606 } 1607 1608 /*--------------------------------------------------------------------*//*! 1609 * \brief Map Vulkan sampler parameters to tcu::Sampler. 1610 * 1611 * If no mapping is found, throws tcu::InternalError. 1612 * 1613 * \param wrapU U-component wrap mode 1614 * \param wrapV V-component wrap mode 1615 * \param minFilterMode Minification filter mode 1616 * \param minFilterMode Magnification filter mode 1617 * \return Sampler description. 1618 *//*--------------------------------------------------------------------*/ 1619 tcu::Sampler createSampler (tcu::Sampler::WrapMode wrapU, tcu::Sampler::WrapMode wrapV, tcu::Sampler::FilterMode minFilterMode, tcu::Sampler::FilterMode magFilterMode) 1620 { 1621 return createSampler(wrapU, wrapV, wrapU, minFilterMode, magFilterMode); 1622 } 1623 1624 /*--------------------------------------------------------------------*//*! 1625 * \brief Map Vulkan sampler parameters to tcu::Sampler. 1626 * 1627 * If no mapping is found, throws tcu::InternalError. 1628 * 1629 * \param wrapU U-component wrap mode 1630 * \param minFilterMode Minification filter mode 1631 * \return Sampler description. 1632 *//*--------------------------------------------------------------------*/ 1633 tcu::Sampler createSampler (tcu::Sampler::WrapMode wrapU, tcu::Sampler::FilterMode minFilterMode, tcu::Sampler::FilterMode magFilterMode) 1634 { 1635 return createSampler(wrapU, wrapU, wrapU, minFilterMode, magFilterMode); 1636 } 1637 1638 TestTexture2DSp loadTexture2D (const tcu::Archive& archive, const std::vector<std::string>& filenames) 1639 { 1640 DE_ASSERT(filenames.size() > 0); 1641 1642 TestTexture2DSp texture; 1643 1644 std::string ext = de::FilePath(filenames[0]).getFileExtension(); 1645 1646 if (ext == "png") 1647 { 1648 1649 for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex) 1650 { 1651 tcu::TextureLevel level; 1652 1653 tcu::ImageIO::loadImage(level, archive, filenames[fileIndex].c_str()); 1654 1655 TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) || 1656 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8)); 1657 1658 if (fileIndex == 0) 1659 texture = TestTexture2DSp(new pipeline::TestTexture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth(), level.getHeight())); 1660 1661 tcu::copy(texture->getLevel((int)fileIndex, 0), level.getAccess()); 1662 } 1663 } 1664 else if (ext == "pkm") 1665 { 1666 1667 for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex) 1668 { 1669 // Compressed texture. 1670 tcu::CompressedTexture level; 1671 1672 tcu::ImageIO::loadPKM(level, archive, filenames[fileIndex].c_str()); 1673 1674 tcu::TextureFormat uncompressedFormat = tcu::getUncompressedFormat(level.getFormat()); 1675 std::vector<deUint8> uncompressedData (uncompressedFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0); 1676 tcu::PixelBufferAccess decompressedBuffer (uncompressedFormat, level.getWidth(), level.getHeight(), 1, uncompressedData.data()); 1677 1678 tcu::TextureFormat commonFormat = tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8); 1679 std::vector<deUint8> commonFromatData (commonFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0); 1680 tcu::PixelBufferAccess commonFormatBuffer (commonFormat, level.getWidth(), level.getHeight(), 1, commonFromatData.data()); 1681 1682 if (fileIndex == 0) 1683 texture = TestTexture2DSp(new pipeline::TestTexture2D(commonFormat, level.getWidth(), level.getHeight())); 1684 1685 level.decompress(decompressedBuffer, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR)); 1686 1687 tcu::copy(commonFormatBuffer, decompressedBuffer); 1688 tcu::copy(texture->getLevel((int)fileIndex, 0), commonFormatBuffer); 1689 } 1690 } 1691 else 1692 TCU_FAIL("Unsupported file format"); 1693 1694 return texture; 1695 } 1696 1697 TestTextureCubeSp loadTextureCube (const tcu::Archive& archive, const std::vector<std::string>& filenames) 1698 { 1699 DE_ASSERT(filenames.size() > 0); 1700 DE_STATIC_ASSERT(tcu::CUBEFACE_LAST == 6); 1701 TCU_CHECK((int)filenames.size() % tcu::CUBEFACE_LAST == 0); 1702 1703 TestTextureCubeSp texture; 1704 1705 std::string ext = de::FilePath(filenames[0]).getFileExtension(); 1706 1707 if (ext == "png") 1708 { 1709 1710 for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex) 1711 { 1712 tcu::TextureLevel level; 1713 1714 tcu::ImageIO::loadImage(level, archive, filenames[fileIndex].c_str()); 1715 1716 TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) || 1717 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8)); 1718 1719 TCU_CHECK( level.getWidth() == level.getHeight()); 1720 1721 if (fileIndex == 0) 1722 texture = TestTextureCubeSp(new pipeline::TestTextureCube(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), level.getWidth())); 1723 1724 tcu::copy(texture->getLevel((int)fileIndex / 6, (int)fileIndex % 6), level.getAccess()); 1725 } 1726 } 1727 else if (ext == "pkm") 1728 { 1729 for (size_t fileIndex = 0; fileIndex < filenames.size(); ++fileIndex) 1730 { 1731 // Compressed texture. 1732 tcu::CompressedTexture level; 1733 1734 tcu::ImageIO::loadPKM(level, archive, filenames[fileIndex].c_str()); 1735 1736 TCU_CHECK( level.getWidth() == level.getHeight()); 1737 1738 tcu::TextureFormat uncompressedFormat = tcu::getUncompressedFormat(level.getFormat()); 1739 std::vector<deUint8> uncompressedData (uncompressedFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0); 1740 tcu::PixelBufferAccess decompressedBuffer (uncompressedFormat, level.getWidth(), level.getHeight(), 1, uncompressedData.data()); 1741 1742 tcu::TextureFormat commonFormat = tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8); 1743 std::vector<deUint8> commonFromatData (commonFormat.getPixelSize() * level.getWidth() * level.getHeight(), 0); 1744 tcu::PixelBufferAccess commonFormatBuffer (commonFormat, level.getWidth(), level.getHeight(), 1, commonFromatData.data()); 1745 1746 if (fileIndex == 0) 1747 texture = TestTextureCubeSp(new pipeline::TestTextureCube(commonFormat, level.getWidth())); 1748 1749 level.decompress(decompressedBuffer, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR)); 1750 1751 tcu::copy(commonFormatBuffer, decompressedBuffer); 1752 tcu::copy(texture->getLevel((int)fileIndex / 6, (int)fileIndex % 6), commonFormatBuffer); 1753 } 1754 } 1755 else 1756 TCU_FAIL("Unsupported file format"); 1757 1758 return texture; 1759 } 1760 1761 TextureCommonTestCaseParameters::TextureCommonTestCaseParameters (void) 1762 : sampleCount (VK_SAMPLE_COUNT_1_BIT) 1763 , texCoordPrecision (glu::PRECISION_HIGHP) 1764 , minFilter (tcu::Sampler::LINEAR) 1765 , magFilter (tcu::Sampler::LINEAR) 1766 , wrapS (tcu::Sampler::REPEAT_GL) 1767 , wrapT (tcu::Sampler::REPEAT_GL) 1768 , format (VK_FORMAT_R8G8B8A8_UNORM) 1769 { 1770 } 1771 1772 Texture2DTestCaseParameters::Texture2DTestCaseParameters (void) 1773 : width (64) 1774 , height (64) 1775 { 1776 } 1777 1778 TextureCubeTestCaseParameters::TextureCubeTestCaseParameters (void) 1779 : size (64) 1780 { 1781 } 1782 1783 Texture2DArrayTestCaseParameters::Texture2DArrayTestCaseParameters (void) 1784 : numLayers (8) 1785 { 1786 } 1787 1788 Texture3DTestCaseParameters::Texture3DTestCaseParameters (void) 1789 : wrapR (tcu::Sampler::REPEAT_GL) 1790 , depth (64) 1791 { 1792 } 1793 1794 } // util 1795 } // texture 1796 } // vkt 1797