1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------ 2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests 3e5c31af7Sopenharmony_ci * ------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2016 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * Copyright (c) 2016 The Android Open Source Project 7e5c31af7Sopenharmony_ci * 8e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 9e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 10e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 11e5c31af7Sopenharmony_ci * 12e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 13e5c31af7Sopenharmony_ci * 14e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 15e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 16e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 18e5c31af7Sopenharmony_ci * limitations under the License. 19e5c31af7Sopenharmony_ci * 20e5c31af7Sopenharmony_ci *//*! 21e5c31af7Sopenharmony_ci * \file 22e5c31af7Sopenharmony_ci * \brief Image load/store Tests 23e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 24e5c31af7Sopenharmony_ci 25e5c31af7Sopenharmony_ci#include "vktImageLoadStoreTests.hpp" 26e5c31af7Sopenharmony_ci#include "vktTestCaseUtil.hpp" 27e5c31af7Sopenharmony_ci#include "vktImageTestsUtil.hpp" 28e5c31af7Sopenharmony_ci#include "vktImageLoadStoreUtil.hpp" 29e5c31af7Sopenharmony_ci#include "vktImageTexture.hpp" 30e5c31af7Sopenharmony_ci 31e5c31af7Sopenharmony_ci#include "vkDefs.hpp" 32e5c31af7Sopenharmony_ci#include "vkRef.hpp" 33e5c31af7Sopenharmony_ci#include "vkRefUtil.hpp" 34e5c31af7Sopenharmony_ci#include "vkPlatform.hpp" 35e5c31af7Sopenharmony_ci#include "vkPrograms.hpp" 36e5c31af7Sopenharmony_ci#include "vkMemUtil.hpp" 37e5c31af7Sopenharmony_ci#include "vkBarrierUtil.hpp" 38e5c31af7Sopenharmony_ci#include "vkBuilderUtil.hpp" 39e5c31af7Sopenharmony_ci#include "vkQueryUtil.hpp" 40e5c31af7Sopenharmony_ci#include "vkImageUtil.hpp" 41e5c31af7Sopenharmony_ci#include "vkCmdUtil.hpp" 42e5c31af7Sopenharmony_ci#include "vkObjUtil.hpp" 43e5c31af7Sopenharmony_ci#include "vkBufferWithMemory.hpp" 44e5c31af7Sopenharmony_ci 45e5c31af7Sopenharmony_ci#include "deMath.h" 46e5c31af7Sopenharmony_ci#include "deUniquePtr.hpp" 47e5c31af7Sopenharmony_ci#include "deSharedPtr.hpp" 48e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 49e5c31af7Sopenharmony_ci 50e5c31af7Sopenharmony_ci#include "tcuImageCompare.hpp" 51e5c31af7Sopenharmony_ci#include "tcuTexture.hpp" 52e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp" 53e5c31af7Sopenharmony_ci#include "tcuFloat.hpp" 54e5c31af7Sopenharmony_ci#include "tcuFloatFormat.hpp" 55e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp" 56e5c31af7Sopenharmony_ci#include "tcuVectorUtil.hpp" 57e5c31af7Sopenharmony_ci 58e5c31af7Sopenharmony_ci#include <string> 59e5c31af7Sopenharmony_ci#include <vector> 60e5c31af7Sopenharmony_ci#include <map> 61e5c31af7Sopenharmony_ci 62e5c31af7Sopenharmony_ciusing namespace vk; 63e5c31af7Sopenharmony_ci 64e5c31af7Sopenharmony_cinamespace vkt 65e5c31af7Sopenharmony_ci{ 66e5c31af7Sopenharmony_cinamespace image 67e5c31af7Sopenharmony_ci{ 68e5c31af7Sopenharmony_cinamespace 69e5c31af7Sopenharmony_ci{ 70e5c31af7Sopenharmony_ci 71e5c31af7Sopenharmony_ci// Check for three-component (non-packed) format, i.e. pixel size is a multiple of 3. 72e5c31af7Sopenharmony_cibool formatHasThreeComponents(VkFormat format) 73e5c31af7Sopenharmony_ci{ 74e5c31af7Sopenharmony_ci const tcu::TextureFormat texFormat = mapVkFormat(format); 75e5c31af7Sopenharmony_ci return (getPixelSize(texFormat) % 3) == 0; 76e5c31af7Sopenharmony_ci} 77e5c31af7Sopenharmony_ci 78e5c31af7Sopenharmony_ciVkFormat getSingleComponentFormat(VkFormat format) 79e5c31af7Sopenharmony_ci{ 80e5c31af7Sopenharmony_ci tcu::TextureFormat texFormat = mapVkFormat(format); 81e5c31af7Sopenharmony_ci texFormat = tcu::TextureFormat(tcu::TextureFormat::R, texFormat.type); 82e5c31af7Sopenharmony_ci return mapTextureFormat(texFormat); 83e5c31af7Sopenharmony_ci} 84e5c31af7Sopenharmony_ci 85e5c31af7Sopenharmony_ciinline VkBufferImageCopy makeBufferImageCopy (const Texture& texture) 86e5c31af7Sopenharmony_ci{ 87e5c31af7Sopenharmony_ci return image::makeBufferImageCopy(makeExtent3D(texture.layerSize()), texture.numLayers()); 88e5c31af7Sopenharmony_ci} 89e5c31af7Sopenharmony_ci 90e5c31af7Sopenharmony_citcu::ConstPixelBufferAccess getLayerOrSlice (const Texture& texture, const tcu::ConstPixelBufferAccess access, const int layer) 91e5c31af7Sopenharmony_ci{ 92e5c31af7Sopenharmony_ci switch (texture.type()) 93e5c31af7Sopenharmony_ci { 94e5c31af7Sopenharmony_ci case IMAGE_TYPE_1D: 95e5c31af7Sopenharmony_ci case IMAGE_TYPE_2D: 96e5c31af7Sopenharmony_ci case IMAGE_TYPE_BUFFER: 97e5c31af7Sopenharmony_ci // Not layered 98e5c31af7Sopenharmony_ci DE_ASSERT(layer == 0); 99e5c31af7Sopenharmony_ci return access; 100e5c31af7Sopenharmony_ci 101e5c31af7Sopenharmony_ci case IMAGE_TYPE_1D_ARRAY: 102e5c31af7Sopenharmony_ci return tcu::getSubregion(access, 0, layer, access.getWidth(), 1); 103e5c31af7Sopenharmony_ci 104e5c31af7Sopenharmony_ci case IMAGE_TYPE_2D_ARRAY: 105e5c31af7Sopenharmony_ci case IMAGE_TYPE_CUBE: 106e5c31af7Sopenharmony_ci case IMAGE_TYPE_CUBE_ARRAY: 107e5c31af7Sopenharmony_ci case IMAGE_TYPE_3D: // 3d texture is treated as if depth was the layers 108e5c31af7Sopenharmony_ci return tcu::getSubregion(access, 0, 0, layer, access.getWidth(), access.getHeight(), 1); 109e5c31af7Sopenharmony_ci 110e5c31af7Sopenharmony_ci default: 111e5c31af7Sopenharmony_ci DE_FATAL("Internal test error"); 112e5c31af7Sopenharmony_ci return tcu::ConstPixelBufferAccess(); 113e5c31af7Sopenharmony_ci } 114e5c31af7Sopenharmony_ci} 115e5c31af7Sopenharmony_ci 116e5c31af7Sopenharmony_ci//! \return the size in bytes of a given level of a mipmap image, including array layers. 117e5c31af7Sopenharmony_civk::VkDeviceSize getMipmapLevelImageSizeBytes (const Texture& texture, const vk::VkFormat format, const deUint32 mipmapLevel) 118e5c31af7Sopenharmony_ci{ 119e5c31af7Sopenharmony_ci tcu::IVec3 size = texture.size(mipmapLevel); 120e5c31af7Sopenharmony_ci return tcu::getPixelSize(vk::mapVkFormat(format)) * size.x() * size.y() * size.z(); 121e5c31af7Sopenharmony_ci} 122e5c31af7Sopenharmony_ci 123e5c31af7Sopenharmony_ci//! \return the size in bytes of the whole mipmap image, including all mipmap levels and array layers 124e5c31af7Sopenharmony_civk::VkDeviceSize getMipmapImageTotalSizeBytes (const Texture& texture, const vk::VkFormat format) 125e5c31af7Sopenharmony_ci{ 126e5c31af7Sopenharmony_ci vk::VkDeviceSize size = 0u; 127e5c31af7Sopenharmony_ci deInt32 levelCount = 0u; 128e5c31af7Sopenharmony_ci 129e5c31af7Sopenharmony_ci do 130e5c31af7Sopenharmony_ci { 131e5c31af7Sopenharmony_ci size += getMipmapLevelImageSizeBytes(texture, format, levelCount); 132e5c31af7Sopenharmony_ci levelCount++; 133e5c31af7Sopenharmony_ci } while (levelCount < texture.numMipmapLevels()); 134e5c31af7Sopenharmony_ci return size; 135e5c31af7Sopenharmony_ci} 136e5c31af7Sopenharmony_ci 137e5c31af7Sopenharmony_ci//! \return true if all layers match in both pixel buffers 138e5c31af7Sopenharmony_cibool comparePixelBuffers (tcu::TestLog& log, 139e5c31af7Sopenharmony_ci const Texture& texture, 140e5c31af7Sopenharmony_ci const VkFormat format, 141e5c31af7Sopenharmony_ci const tcu::ConstPixelBufferAccess reference, 142e5c31af7Sopenharmony_ci const tcu::ConstPixelBufferAccess result, 143e5c31af7Sopenharmony_ci const deUint32 mipmapLevel = 0u) 144e5c31af7Sopenharmony_ci{ 145e5c31af7Sopenharmony_ci DE_ASSERT(reference.getFormat() == result.getFormat()); 146e5c31af7Sopenharmony_ci DE_ASSERT(reference.getSize() == result.getSize()); 147e5c31af7Sopenharmony_ci 148e5c31af7Sopenharmony_ci const bool is3d = (texture.type() == IMAGE_TYPE_3D); 149e5c31af7Sopenharmony_ci const int numLayersOrSlices = (is3d ? texture.size(mipmapLevel).z() : texture.numLayers()); 150e5c31af7Sopenharmony_ci const int numCubeFaces = 6; 151e5c31af7Sopenharmony_ci 152e5c31af7Sopenharmony_ci int passedLayers = 0; 153e5c31af7Sopenharmony_ci for (int layerNdx = 0; layerNdx < numLayersOrSlices; ++layerNdx) 154e5c31af7Sopenharmony_ci { 155e5c31af7Sopenharmony_ci const std::string comparisonName = "Comparison" + de::toString(layerNdx); 156e5c31af7Sopenharmony_ci const std::string comparisonDesc = "Image Comparison, " + 157e5c31af7Sopenharmony_ci (isCube(texture) ? "face " + de::toString(layerNdx % numCubeFaces) + ", cube " + de::toString(layerNdx / numCubeFaces) : 158e5c31af7Sopenharmony_ci is3d ? "slice " + de::toString(layerNdx) : "layer " + de::toString(layerNdx) + " , level " + de::toString(mipmapLevel)); 159e5c31af7Sopenharmony_ci 160e5c31af7Sopenharmony_ci const tcu::ConstPixelBufferAccess refLayer = getLayerOrSlice(texture, reference, layerNdx); 161e5c31af7Sopenharmony_ci const tcu::ConstPixelBufferAccess resultLayer = getLayerOrSlice(texture, result, layerNdx); 162e5c31af7Sopenharmony_ci 163e5c31af7Sopenharmony_ci bool ok = false; 164e5c31af7Sopenharmony_ci 165e5c31af7Sopenharmony_ci switch (tcu::getTextureChannelClass(mapVkFormat(format).type)) 166e5c31af7Sopenharmony_ci { 167e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 168e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 169e5c31af7Sopenharmony_ci { 170e5c31af7Sopenharmony_ci ok = tcu::intThresholdCompare(log, comparisonName.c_str(), comparisonDesc.c_str(), refLayer, resultLayer, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT); 171e5c31af7Sopenharmony_ci break; 172e5c31af7Sopenharmony_ci } 173e5c31af7Sopenharmony_ci 174e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 175e5c31af7Sopenharmony_ci { 176e5c31af7Sopenharmony_ci // Allow error of minimum representable difference 177e5c31af7Sopenharmony_ci tcu::Vec4 threshold(1.0f / ((tcu::UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(mapVkFormat(format)).cast<deUint32>()) - 1u).cast<float>()); 178e5c31af7Sopenharmony_ci 179e5c31af7Sopenharmony_ci // Add 1 ULP of fp32 imprecision to account for image comparison fp32 math with unorm->float conversions. 180e5c31af7Sopenharmony_ci threshold += tcu::Vec4(std::numeric_limits<float>::epsilon()); 181e5c31af7Sopenharmony_ci 182e5c31af7Sopenharmony_ci ok = tcu::floatThresholdCompare(log, comparisonName.c_str(), comparisonDesc.c_str(), refLayer, resultLayer, threshold, tcu::COMPARE_LOG_RESULT); 183e5c31af7Sopenharmony_ci break; 184e5c31af7Sopenharmony_ci } 185e5c31af7Sopenharmony_ci 186e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 187e5c31af7Sopenharmony_ci { 188e5c31af7Sopenharmony_ci const tcu::UVec4 bitDepth = tcu::getTextureFormatMantissaBitDepth(mapVkFormat(format)).cast<deUint32>() - 1u; 189e5c31af7Sopenharmony_ci // To avoid bit-shifting with negative value, which is undefined behaviour. 190e5c31af7Sopenharmony_ci const tcu::UVec4 fixedBitDepth = tcu::select(bitDepth, tcu::UVec4(0u, 0u, 0u, 0u), tcu::greaterThanEqual(bitDepth.cast<deInt32>(), tcu::IVec4(0, 0, 0, 0))); 191e5c31af7Sopenharmony_ci 192e5c31af7Sopenharmony_ci // Allow error of minimum representable difference 193e5c31af7Sopenharmony_ci const tcu::Vec4 threshold (1.0f / ((tcu::UVec4(1u) << fixedBitDepth) - 1u).cast<float>()); 194e5c31af7Sopenharmony_ci 195e5c31af7Sopenharmony_ci ok = tcu::floatThresholdCompare(log, comparisonName.c_str(), comparisonDesc.c_str(), refLayer, resultLayer, threshold, tcu::COMPARE_LOG_RESULT); 196e5c31af7Sopenharmony_ci break; 197e5c31af7Sopenharmony_ci } 198e5c31af7Sopenharmony_ci 199e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 200e5c31af7Sopenharmony_ci { 201e5c31af7Sopenharmony_ci // Convert target format ulps to float ulps and allow 1 ulp difference 202e5c31af7Sopenharmony_ci const tcu::UVec4 threshold (tcu::UVec4(1u) << (tcu::UVec4(23) - tcu::getTextureFormatMantissaBitDepth(mapVkFormat(format)).cast<deUint32>())); 203e5c31af7Sopenharmony_ci 204e5c31af7Sopenharmony_ci ok = tcu::floatUlpThresholdCompare(log, comparisonName.c_str(), comparisonDesc.c_str(), refLayer, resultLayer, threshold, tcu::COMPARE_LOG_RESULT); 205e5c31af7Sopenharmony_ci break; 206e5c31af7Sopenharmony_ci } 207e5c31af7Sopenharmony_ci 208e5c31af7Sopenharmony_ci default: 209e5c31af7Sopenharmony_ci DE_FATAL("Unknown channel class"); 210e5c31af7Sopenharmony_ci } 211e5c31af7Sopenharmony_ci 212e5c31af7Sopenharmony_ci if (ok) 213e5c31af7Sopenharmony_ci ++passedLayers; 214e5c31af7Sopenharmony_ci } 215e5c31af7Sopenharmony_ci 216e5c31af7Sopenharmony_ci return passedLayers == numLayersOrSlices; 217e5c31af7Sopenharmony_ci} 218e5c31af7Sopenharmony_ci 219e5c31af7Sopenharmony_ci//!< Zero out invalid pixels in the image (denormalized, infinite, NaN values) 220e5c31af7Sopenharmony_civoid replaceBadFloatReinterpretValues (const tcu::PixelBufferAccess access) 221e5c31af7Sopenharmony_ci{ 222e5c31af7Sopenharmony_ci DE_ASSERT(tcu::getTextureChannelClass(access.getFormat().type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT); 223e5c31af7Sopenharmony_ci 224e5c31af7Sopenharmony_ci for (int z = 0; z < access.getDepth(); ++z) 225e5c31af7Sopenharmony_ci for (int y = 0; y < access.getHeight(); ++y) 226e5c31af7Sopenharmony_ci for (int x = 0; x < access.getWidth(); ++x) 227e5c31af7Sopenharmony_ci { 228e5c31af7Sopenharmony_ci const tcu::Vec4 color(access.getPixel(x, y, z)); 229e5c31af7Sopenharmony_ci tcu::Vec4 newColor = color; 230e5c31af7Sopenharmony_ci 231e5c31af7Sopenharmony_ci for (int i = 0; i < 4; ++i) 232e5c31af7Sopenharmony_ci { 233e5c31af7Sopenharmony_ci if (access.getFormat().type == tcu::TextureFormat::HALF_FLOAT) 234e5c31af7Sopenharmony_ci { 235e5c31af7Sopenharmony_ci const tcu::Float16 f(color[i]); 236e5c31af7Sopenharmony_ci if (f.isDenorm() || f.isInf() || f.isNaN()) 237e5c31af7Sopenharmony_ci newColor[i] = 0.0f; 238e5c31af7Sopenharmony_ci } 239e5c31af7Sopenharmony_ci else 240e5c31af7Sopenharmony_ci { 241e5c31af7Sopenharmony_ci const tcu::Float32 f(color[i]); 242e5c31af7Sopenharmony_ci if (f.isDenorm() || f.isInf() || f.isNaN()) 243e5c31af7Sopenharmony_ci newColor[i] = 0.0f; 244e5c31af7Sopenharmony_ci } 245e5c31af7Sopenharmony_ci } 246e5c31af7Sopenharmony_ci 247e5c31af7Sopenharmony_ci if (newColor != color) 248e5c31af7Sopenharmony_ci access.setPixel(newColor, x, y, z); 249e5c31af7Sopenharmony_ci } 250e5c31af7Sopenharmony_ci} 251e5c31af7Sopenharmony_ci 252e5c31af7Sopenharmony_ci//!< replace invalid pixels in the image (-128) 253e5c31af7Sopenharmony_civoid replaceSnormReinterpretValues (const tcu::PixelBufferAccess access) 254e5c31af7Sopenharmony_ci{ 255e5c31af7Sopenharmony_ci DE_ASSERT(tcu::getTextureChannelClass(access.getFormat().type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT); 256e5c31af7Sopenharmony_ci 257e5c31af7Sopenharmony_ci for (int z = 0; z < access.getDepth(); ++z) 258e5c31af7Sopenharmony_ci for (int y = 0; y < access.getHeight(); ++y) 259e5c31af7Sopenharmony_ci for (int x = 0; x < access.getWidth(); ++x) 260e5c31af7Sopenharmony_ci { 261e5c31af7Sopenharmony_ci const tcu::IVec4 color(access.getPixelInt(x, y, z)); 262e5c31af7Sopenharmony_ci tcu::IVec4 newColor = color; 263e5c31af7Sopenharmony_ci 264e5c31af7Sopenharmony_ci for (int i = 0; i < 4; ++i) 265e5c31af7Sopenharmony_ci { 266e5c31af7Sopenharmony_ci const deInt32 oldColor(color[i]); 267e5c31af7Sopenharmony_ci if (oldColor == -128) newColor[i] = -127; 268e5c31af7Sopenharmony_ci } 269e5c31af7Sopenharmony_ci 270e5c31af7Sopenharmony_ci if (newColor != color) 271e5c31af7Sopenharmony_ci access.setPixel(newColor, x, y, z); 272e5c31af7Sopenharmony_ci } 273e5c31af7Sopenharmony_ci} 274e5c31af7Sopenharmony_ci 275e5c31af7Sopenharmony_citcu::Vec4 getMiddleValue(VkFormat imageFormat) 276e5c31af7Sopenharmony_ci{ 277e5c31af7Sopenharmony_ci tcu::TextureFormat format = mapVkFormat(imageFormat); 278e5c31af7Sopenharmony_ci tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(format); 279e5c31af7Sopenharmony_ci tcu::Vec4 val = (fmtInfo.valueMax - fmtInfo.valueMin) * tcu::Vec4(0.5f); 280e5c31af7Sopenharmony_ci 281e5c31af7Sopenharmony_ci if (isIntegerFormat(imageFormat)) 282e5c31af7Sopenharmony_ci val = floor(val); 283e5c31af7Sopenharmony_ci 284e5c31af7Sopenharmony_ci return val; 285e5c31af7Sopenharmony_ci} 286e5c31af7Sopenharmony_ci 287e5c31af7Sopenharmony_citcu::TextureLevel generateReferenceImage (const tcu::IVec3& imageSize, const VkFormat imageFormat, const VkFormat readFormat, bool constantValue = false) 288e5c31af7Sopenharmony_ci{ 289e5c31af7Sopenharmony_ci // Generate a reference image data using the storage format 290e5c31af7Sopenharmony_ci 291e5c31af7Sopenharmony_ci tcu::TextureLevel reference(mapVkFormat(imageFormat), imageSize.x(), imageSize.y(), imageSize.z()); 292e5c31af7Sopenharmony_ci const tcu::PixelBufferAccess access = reference.getAccess(); 293e5c31af7Sopenharmony_ci 294e5c31af7Sopenharmony_ci const float storeColorScale = computeStoreColorScale(imageFormat, imageSize); 295e5c31af7Sopenharmony_ci const float storeColorBias = computeStoreColorBias(imageFormat); 296e5c31af7Sopenharmony_ci 297e5c31af7Sopenharmony_ci const bool srgbFormat = isSrgbFormat(imageFormat); 298e5c31af7Sopenharmony_ci const bool intFormat = isIntegerFormat(imageFormat); 299e5c31af7Sopenharmony_ci const bool storeNegativeValues = isSignedFormat(imageFormat) && (storeColorBias == 0); 300e5c31af7Sopenharmony_ci const int xMax = imageSize.x() - 1; 301e5c31af7Sopenharmony_ci const int yMax = imageSize.y() - 1; 302e5c31af7Sopenharmony_ci 303e5c31af7Sopenharmony_ci for (int z = 0; z < imageSize.z(); ++z) 304e5c31af7Sopenharmony_ci for (int y = 0; y < imageSize.y(); ++y) 305e5c31af7Sopenharmony_ci for (int x = 0; x < imageSize.x(); ++x) 306e5c31af7Sopenharmony_ci { 307e5c31af7Sopenharmony_ci if (constantValue) 308e5c31af7Sopenharmony_ci { 309e5c31af7Sopenharmony_ci access.setPixel(getMiddleValue(imageFormat), x, y, z); 310e5c31af7Sopenharmony_ci } 311e5c31af7Sopenharmony_ci else 312e5c31af7Sopenharmony_ci { 313e5c31af7Sopenharmony_ci tcu::IVec4 color = tcu::IVec4(x ^ y ^ z, (xMax - x) ^ y ^ z, x ^ (yMax - y) ^ z, (xMax - x) ^ (yMax - y) ^ z); 314e5c31af7Sopenharmony_ci 315e5c31af7Sopenharmony_ci if (storeNegativeValues) 316e5c31af7Sopenharmony_ci color -= tcu::IVec4(deRoundFloatToInt32((float)de::max(xMax, yMax) / 2.0f)); 317e5c31af7Sopenharmony_ci 318e5c31af7Sopenharmony_ci if (intFormat) 319e5c31af7Sopenharmony_ci access.setPixel(color, x, y, z); 320e5c31af7Sopenharmony_ci else 321e5c31af7Sopenharmony_ci { 322e5c31af7Sopenharmony_ci if (srgbFormat) 323e5c31af7Sopenharmony_ci access.setPixel(tcu::linearToSRGB(color.asFloat() * storeColorScale + storeColorBias), x, y, z); 324e5c31af7Sopenharmony_ci else 325e5c31af7Sopenharmony_ci access.setPixel(color.asFloat() * storeColorScale + storeColorBias, x, y, z); 326e5c31af7Sopenharmony_ci } 327e5c31af7Sopenharmony_ci } 328e5c31af7Sopenharmony_ci } 329e5c31af7Sopenharmony_ci 330e5c31af7Sopenharmony_ci // If the image is to be accessed as a float texture, get rid of invalid values 331e5c31af7Sopenharmony_ci 332e5c31af7Sopenharmony_ci if (isFloatFormat(readFormat) && imageFormat != readFormat) 333e5c31af7Sopenharmony_ci replaceBadFloatReinterpretValues(tcu::PixelBufferAccess(mapVkFormat(readFormat), imageSize, access.getDataPtr())); 334e5c31af7Sopenharmony_ci if (isSnormFormat(readFormat) && imageFormat != readFormat) 335e5c31af7Sopenharmony_ci replaceSnormReinterpretValues(tcu::PixelBufferAccess(mapVkFormat(readFormat), imageSize, access.getDataPtr())); 336e5c31af7Sopenharmony_ci 337e5c31af7Sopenharmony_ci return reference; 338e5c31af7Sopenharmony_ci} 339e5c31af7Sopenharmony_ci 340e5c31af7Sopenharmony_ciinline tcu::TextureLevel generateReferenceImage (const tcu::IVec3& imageSize, const VkFormat imageFormat, bool constantValue = false) 341e5c31af7Sopenharmony_ci{ 342e5c31af7Sopenharmony_ci return generateReferenceImage(imageSize, imageFormat, imageFormat, constantValue); 343e5c31af7Sopenharmony_ci} 344e5c31af7Sopenharmony_ci 345e5c31af7Sopenharmony_civoid flipHorizontally (const tcu::PixelBufferAccess access) 346e5c31af7Sopenharmony_ci{ 347e5c31af7Sopenharmony_ci const int xMax = access.getWidth() - 1; 348e5c31af7Sopenharmony_ci const int halfWidth = access.getWidth() / 2; 349e5c31af7Sopenharmony_ci 350e5c31af7Sopenharmony_ci if (isIntegerFormat(mapTextureFormat(access.getFormat()))) 351e5c31af7Sopenharmony_ci for (int z = 0; z < access.getDepth(); z++) 352e5c31af7Sopenharmony_ci for (int y = 0; y < access.getHeight(); y++) 353e5c31af7Sopenharmony_ci for (int x = 0; x < halfWidth; x++) 354e5c31af7Sopenharmony_ci { 355e5c31af7Sopenharmony_ci const tcu::UVec4 temp = access.getPixelUint(xMax - x, y, z); 356e5c31af7Sopenharmony_ci access.setPixel(access.getPixelUint(x, y, z), xMax - x, y, z); 357e5c31af7Sopenharmony_ci access.setPixel(temp, x, y, z); 358e5c31af7Sopenharmony_ci } 359e5c31af7Sopenharmony_ci else 360e5c31af7Sopenharmony_ci for (int z = 0; z < access.getDepth(); z++) 361e5c31af7Sopenharmony_ci for (int y = 0; y < access.getHeight(); y++) 362e5c31af7Sopenharmony_ci for (int x = 0; x < halfWidth; x++) 363e5c31af7Sopenharmony_ci { 364e5c31af7Sopenharmony_ci const tcu::Vec4 temp = access.getPixel(xMax - x, y, z); 365e5c31af7Sopenharmony_ci access.setPixel(access.getPixel(x, y, z), xMax - x, y, z); 366e5c31af7Sopenharmony_ci access.setPixel(temp, x, y, z); 367e5c31af7Sopenharmony_ci } 368e5c31af7Sopenharmony_ci} 369e5c31af7Sopenharmony_ci 370e5c31af7Sopenharmony_ciinline bool formatsAreCompatible (const VkFormat format0, const VkFormat format1) 371e5c31af7Sopenharmony_ci{ 372e5c31af7Sopenharmony_ci const bool isAlphaOnly = (isAlphaOnlyFormat(format0) || isAlphaOnlyFormat(format1)); 373e5c31af7Sopenharmony_ci return format0 == format1 || (mapVkFormat(format0).getPixelSize() == mapVkFormat(format1).getPixelSize() && !isAlphaOnly); 374e5c31af7Sopenharmony_ci} 375e5c31af7Sopenharmony_ci 376e5c31af7Sopenharmony_civoid commandImageWriteBarrierBetweenShaderInvocations (Context& context, const VkCommandBuffer cmdBuffer, const VkImage image, const Texture& texture) 377e5c31af7Sopenharmony_ci{ 378e5c31af7Sopenharmony_ci const DeviceInterface& vk = context.getDeviceInterface(); 379e5c31af7Sopenharmony_ci 380e5c31af7Sopenharmony_ci const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, texture.numMipmapLevels(), 0u, texture.numLayers()); 381e5c31af7Sopenharmony_ci const VkImageMemoryBarrier shaderWriteBarrier = makeImageMemoryBarrier( 382e5c31af7Sopenharmony_ci VK_ACCESS_SHADER_WRITE_BIT, 0u, 383e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, 384e5c31af7Sopenharmony_ci image, fullImageSubresourceRange); 385e5c31af7Sopenharmony_ci 386e5c31af7Sopenharmony_ci vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &shaderWriteBarrier); 387e5c31af7Sopenharmony_ci} 388e5c31af7Sopenharmony_ci 389e5c31af7Sopenharmony_civoid commandBufferWriteBarrierBeforeHostRead (Context& context, const VkCommandBuffer cmdBuffer, const VkBuffer buffer, const VkDeviceSize bufferSizeBytes) 390e5c31af7Sopenharmony_ci{ 391e5c31af7Sopenharmony_ci const DeviceInterface& vk = context.getDeviceInterface(); 392e5c31af7Sopenharmony_ci 393e5c31af7Sopenharmony_ci const VkBufferMemoryBarrier shaderWriteBarrier = makeBufferMemoryBarrier( 394e5c31af7Sopenharmony_ci VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, 395e5c31af7Sopenharmony_ci buffer, 0ull, bufferSizeBytes); 396e5c31af7Sopenharmony_ci 397e5c31af7Sopenharmony_ci vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &shaderWriteBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); 398e5c31af7Sopenharmony_ci} 399e5c31af7Sopenharmony_ci 400e5c31af7Sopenharmony_ci//! Copy all layers of an image to a buffer. 401e5c31af7Sopenharmony_civoid commandCopyImageToBuffer (Context& context, 402e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 403e5c31af7Sopenharmony_ci const VkImage image, 404e5c31af7Sopenharmony_ci const VkBuffer buffer, 405e5c31af7Sopenharmony_ci const VkDeviceSize bufferSizeBytes, 406e5c31af7Sopenharmony_ci const Texture& texture) 407e5c31af7Sopenharmony_ci{ 408e5c31af7Sopenharmony_ci const DeviceInterface& vk = context.getDeviceInterface(); 409e5c31af7Sopenharmony_ci 410e5c31af7Sopenharmony_ci const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, texture.numLayers()); 411e5c31af7Sopenharmony_ci const VkImageMemoryBarrier prepareForTransferBarrier = makeImageMemoryBarrier( 412e5c31af7Sopenharmony_ci VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, 413e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 414e5c31af7Sopenharmony_ci image, fullImageSubresourceRange); 415e5c31af7Sopenharmony_ci 416e5c31af7Sopenharmony_ci const VkBufferImageCopy copyRegion = makeBufferImageCopy(texture); 417e5c31af7Sopenharmony_ci 418e5c31af7Sopenharmony_ci const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier( 419e5c31af7Sopenharmony_ci VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, 420e5c31af7Sopenharmony_ci buffer, 0ull, bufferSizeBytes); 421e5c31af7Sopenharmony_ci 422e5c31af7Sopenharmony_ci vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &prepareForTransferBarrier); 423e5c31af7Sopenharmony_ci vk.cmdCopyImageToBuffer(cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, 1u, ©Region); 424e5c31af7Sopenharmony_ci vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, ©Barrier, 0, (const VkImageMemoryBarrier*)DE_NULL); 425e5c31af7Sopenharmony_ci} 426e5c31af7Sopenharmony_ci 427e5c31af7Sopenharmony_ci//! Copy all layers of a mipmap image to a buffer. 428e5c31af7Sopenharmony_civoid commandCopyMipmapImageToBuffer (Context& context, 429e5c31af7Sopenharmony_ci const VkCommandBuffer cmdBuffer, 430e5c31af7Sopenharmony_ci const VkImage image, 431e5c31af7Sopenharmony_ci const VkFormat imageFormat, 432e5c31af7Sopenharmony_ci const VkBuffer buffer, 433e5c31af7Sopenharmony_ci const VkDeviceSize bufferSizeBytes, 434e5c31af7Sopenharmony_ci const Texture& texture) 435e5c31af7Sopenharmony_ci{ 436e5c31af7Sopenharmony_ci const DeviceInterface& vk = context.getDeviceInterface(); 437e5c31af7Sopenharmony_ci 438e5c31af7Sopenharmony_ci const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, texture.numMipmapLevels(), 0u, texture.numLayers()); 439e5c31af7Sopenharmony_ci const VkImageMemoryBarrier prepareForTransferBarrier = makeImageMemoryBarrier( 440e5c31af7Sopenharmony_ci VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, 441e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 442e5c31af7Sopenharmony_ci image, fullImageSubresourceRange); 443e5c31af7Sopenharmony_ci 444e5c31af7Sopenharmony_ci std::vector<VkBufferImageCopy> copyRegions; 445e5c31af7Sopenharmony_ci VkDeviceSize bufferOffset = 0u; 446e5c31af7Sopenharmony_ci for (deInt32 levelNdx = 0; levelNdx < texture.numMipmapLevels(); levelNdx++) 447e5c31af7Sopenharmony_ci { 448e5c31af7Sopenharmony_ci const VkBufferImageCopy copyParams = 449e5c31af7Sopenharmony_ci { 450e5c31af7Sopenharmony_ci bufferOffset, // VkDeviceSize bufferOffset; 451e5c31af7Sopenharmony_ci 0u, // deUint32 bufferRowLength; 452e5c31af7Sopenharmony_ci 0u, // deUint32 bufferImageHeight; 453e5c31af7Sopenharmony_ci makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, levelNdx, 0u, texture.numLayers()), // VkImageSubresourceLayers imageSubresource; 454e5c31af7Sopenharmony_ci makeOffset3D(0, 0, 0), // VkOffset3D imageOffset; 455e5c31af7Sopenharmony_ci makeExtent3D(texture.layerSize(levelNdx)), // VkExtent3D imageExtent; 456e5c31af7Sopenharmony_ci }; 457e5c31af7Sopenharmony_ci copyRegions.push_back(copyParams); 458e5c31af7Sopenharmony_ci bufferOffset += getMipmapLevelImageSizeBytes(texture, imageFormat, levelNdx); 459e5c31af7Sopenharmony_ci } 460e5c31af7Sopenharmony_ci 461e5c31af7Sopenharmony_ci const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier( 462e5c31af7Sopenharmony_ci VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, 463e5c31af7Sopenharmony_ci buffer, 0ull, bufferSizeBytes); 464e5c31af7Sopenharmony_ci 465e5c31af7Sopenharmony_ci vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &prepareForTransferBarrier); 466e5c31af7Sopenharmony_ci vk.cmdCopyImageToBuffer(cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, (deUint32) copyRegions.size(), copyRegions.data()); 467e5c31af7Sopenharmony_ci vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, ©Barrier, 0, (const VkImageMemoryBarrier*)DE_NULL); 468e5c31af7Sopenharmony_ci} 469e5c31af7Sopenharmony_ci 470e5c31af7Sopenharmony_ciclass StoreTest : public TestCase 471e5c31af7Sopenharmony_ci{ 472e5c31af7Sopenharmony_cipublic: 473e5c31af7Sopenharmony_ci enum TestFlags 474e5c31af7Sopenharmony_ci { 475e5c31af7Sopenharmony_ci FLAG_SINGLE_LAYER_BIND = 0x1, //!< Run the shader multiple times, each time binding a different layer. 476e5c31af7Sopenharmony_ci FLAG_DECLARE_IMAGE_FORMAT_IN_SHADER = 0x2, //!< Declare the format of the images in the shader code 477e5c31af7Sopenharmony_ci FLAG_MINALIGN = 0x4, //!< Use bufferview offset that matches the advertised minimum alignment 478e5c31af7Sopenharmony_ci FLAG_STORE_CONSTANT_VALUE = 0x8, //!< Store constant value 479e5c31af7Sopenharmony_ci }; 480e5c31af7Sopenharmony_ci 481e5c31af7Sopenharmony_ci StoreTest (tcu::TestContext& testCtx, 482e5c31af7Sopenharmony_ci const std::string& name, 483e5c31af7Sopenharmony_ci const Texture& texture, 484e5c31af7Sopenharmony_ci const VkFormat format, 485e5c31af7Sopenharmony_ci const VkImageTiling tiling, 486e5c31af7Sopenharmony_ci const deUint32 flags = FLAG_DECLARE_IMAGE_FORMAT_IN_SHADER); 487e5c31af7Sopenharmony_ci 488e5c31af7Sopenharmony_ci virtual void checkSupport (Context& context) const; 489e5c31af7Sopenharmony_ci void initPrograms (SourceCollections& programCollection) const; 490e5c31af7Sopenharmony_ci TestInstance* createInstance (Context& context) const; 491e5c31af7Sopenharmony_ci 492e5c31af7Sopenharmony_ciprivate: 493e5c31af7Sopenharmony_ci const Texture m_texture; 494e5c31af7Sopenharmony_ci const VkFormat m_format; 495e5c31af7Sopenharmony_ci const VkImageTiling m_tiling; 496e5c31af7Sopenharmony_ci const bool m_declareImageFormatInShader; 497e5c31af7Sopenharmony_ci const bool m_singleLayerBind; 498e5c31af7Sopenharmony_ci const bool m_minalign; 499e5c31af7Sopenharmony_ci const bool m_storeConstantValue; 500e5c31af7Sopenharmony_ci}; 501e5c31af7Sopenharmony_ci 502e5c31af7Sopenharmony_ciStoreTest::StoreTest (tcu::TestContext& testCtx, 503e5c31af7Sopenharmony_ci const std::string& name, 504e5c31af7Sopenharmony_ci const Texture& texture, 505e5c31af7Sopenharmony_ci const VkFormat format, 506e5c31af7Sopenharmony_ci const VkImageTiling tiling, 507e5c31af7Sopenharmony_ci const deUint32 flags) 508e5c31af7Sopenharmony_ci : TestCase (testCtx, name) 509e5c31af7Sopenharmony_ci , m_texture (texture) 510e5c31af7Sopenharmony_ci , m_format (format) 511e5c31af7Sopenharmony_ci , m_tiling (tiling) 512e5c31af7Sopenharmony_ci , m_declareImageFormatInShader ((flags & FLAG_DECLARE_IMAGE_FORMAT_IN_SHADER) != 0) 513e5c31af7Sopenharmony_ci , m_singleLayerBind ((flags & FLAG_SINGLE_LAYER_BIND) != 0) 514e5c31af7Sopenharmony_ci , m_minalign ((flags & FLAG_MINALIGN) != 0) 515e5c31af7Sopenharmony_ci , m_storeConstantValue ((flags & FLAG_STORE_CONSTANT_VALUE) != 0) 516e5c31af7Sopenharmony_ci{ 517e5c31af7Sopenharmony_ci if (m_singleLayerBind) 518e5c31af7Sopenharmony_ci DE_ASSERT(m_texture.numLayers() > 1); 519e5c31af7Sopenharmony_ci} 520e5c31af7Sopenharmony_ci 521e5c31af7Sopenharmony_civoid StoreTest::checkSupport (Context& context) const 522e5c31af7Sopenharmony_ci{ 523e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 524e5c31af7Sopenharmony_ci if (m_format == VK_FORMAT_A8_UNORM_KHR || m_format == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR) 525e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_KHR_maintenance5"); 526e5c31af7Sopenharmony_ci 527e5c31af7Sopenharmony_ci const VkFormatProperties3 formatProperties (context.getFormatProperties(m_format)); 528e5c31af7Sopenharmony_ci 529e5c31af7Sopenharmony_ci const auto& tilingFeatures = (m_tiling == vk::VK_IMAGE_TILING_OPTIMAL) ? formatProperties.optimalTilingFeatures : formatProperties.linearTilingFeatures; 530e5c31af7Sopenharmony_ci 531e5c31af7Sopenharmony_ci if ((m_texture.type() == IMAGE_TYPE_BUFFER) && !m_declareImageFormatInShader && !(formatProperties.bufferFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR)) 532e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for unformatted stores via storage buffer"); 533e5c31af7Sopenharmony_ci 534e5c31af7Sopenharmony_ci if ((m_texture.type() != IMAGE_TYPE_BUFFER) && !m_declareImageFormatInShader && !(tilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR)) 535e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for unformatted stores via storage images"); 536e5c31af7Sopenharmony_ci 537e5c31af7Sopenharmony_ci if (m_texture.type() == IMAGE_TYPE_CUBE_ARRAY) 538e5c31af7Sopenharmony_ci context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY); 539e5c31af7Sopenharmony_ci 540e5c31af7Sopenharmony_ci if ((m_texture.type() != IMAGE_TYPE_BUFFER) && !(tilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) 541e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for storage images"); 542e5c31af7Sopenharmony_ci 543e5c31af7Sopenharmony_ci if (m_texture.type() == IMAGE_TYPE_BUFFER && !(formatProperties.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)) 544e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for storage texel buffers"); 545e5c31af7Sopenharmony_ci#else 546e5c31af7Sopenharmony_ci const VkFormatProperties formatProperties(getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), m_format)); 547e5c31af7Sopenharmony_ci const auto tilingFeatures = (m_tiling == vk::VK_IMAGE_TILING_OPTIMAL) ? formatProperties.optimalTilingFeatures : formatProperties.linearTilingFeatures; 548e5c31af7Sopenharmony_ci 549e5c31af7Sopenharmony_ci if (!m_declareImageFormatInShader) 550e5c31af7Sopenharmony_ci context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT); 551e5c31af7Sopenharmony_ci 552e5c31af7Sopenharmony_ci if (m_texture.type() == IMAGE_TYPE_CUBE_ARRAY) 553e5c31af7Sopenharmony_ci context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY); 554e5c31af7Sopenharmony_ci 555e5c31af7Sopenharmony_ci if ((m_texture.type() != IMAGE_TYPE_BUFFER) && !(tilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) 556e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for storage images"); 557e5c31af7Sopenharmony_ci 558e5c31af7Sopenharmony_ci if (m_texture.type() == IMAGE_TYPE_BUFFER && !(formatProperties.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)) 559e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for storage texel buffers"); 560e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 561e5c31af7Sopenharmony_ci 562e5c31af7Sopenharmony_ci const auto& vki = context.getInstanceInterface(); 563e5c31af7Sopenharmony_ci const auto physicalDevice = context.getPhysicalDevice(); 564e5c31af7Sopenharmony_ci 565e5c31af7Sopenharmony_ci VkImageFormatProperties imageFormatProperties; 566e5c31af7Sopenharmony_ci const auto result = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, m_format, mapImageType(m_texture.type()), m_tiling, (VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT), 0, &imageFormatProperties); 567e5c31af7Sopenharmony_ci 568e5c31af7Sopenharmony_ci if (result != VK_SUCCESS) 569e5c31af7Sopenharmony_ci { 570e5c31af7Sopenharmony_ci if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) 571e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format unsupported for tiling"); 572e5c31af7Sopenharmony_ci else 573e5c31af7Sopenharmony_ci TCU_FAIL("vkGetPhysicalDeviceImageFormatProperties returned unexpected error"); 574e5c31af7Sopenharmony_ci } 575e5c31af7Sopenharmony_ci 576e5c31af7Sopenharmony_ci if (imageFormatProperties.maxArrayLayers < (uint32_t)m_texture.numLayers()) { 577e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "This format and tiling combination does not support this number of aray layers"); 578e5c31af7Sopenharmony_ci } 579e5c31af7Sopenharmony_ci 580e5c31af7Sopenharmony_ci if (imageFormatProperties.maxMipLevels < (uint32_t)m_texture.numMipmapLevels()) { 581e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "This format and tiling combination does not support this number of miplevels"); 582e5c31af7Sopenharmony_ci } 583e5c31af7Sopenharmony_ci} 584e5c31af7Sopenharmony_ci 585e5c31af7Sopenharmony_civoid StoreTest::initPrograms (SourceCollections& programCollection) const 586e5c31af7Sopenharmony_ci{ 587e5c31af7Sopenharmony_ci const float storeColorScale = computeStoreColorScale(m_format, m_texture.size()); 588e5c31af7Sopenharmony_ci const float storeColorBias = computeStoreColorBias(m_format); 589e5c31af7Sopenharmony_ci DE_ASSERT(colorScaleAndBiasAreValid(m_format, storeColorScale, storeColorBias)); 590e5c31af7Sopenharmony_ci 591e5c31af7Sopenharmony_ci const deUint32 xMax = m_texture.size().x() - 1; 592e5c31af7Sopenharmony_ci const deUint32 yMax = m_texture.size().y() - 1; 593e5c31af7Sopenharmony_ci const std::string signednessPrefix = isUintFormat(m_format) ? "u" : isIntFormat(m_format) ? "i" : ""; 594e5c31af7Sopenharmony_ci const bool storeNegativeValues = isSignedFormat(m_format) && (storeColorBias == 0); 595e5c31af7Sopenharmony_ci bool useClamp = false; 596e5c31af7Sopenharmony_ci const std::string colorType = signednessPrefix + "vec4"; 597e5c31af7Sopenharmony_ci std::string colorBaseExpr = colorType + "("; 598e5c31af7Sopenharmony_ci 599e5c31af7Sopenharmony_ci std::string colorExpr; 600e5c31af7Sopenharmony_ci 601e5c31af7Sopenharmony_ci if (m_storeConstantValue) 602e5c31af7Sopenharmony_ci { 603e5c31af7Sopenharmony_ci tcu::Vec4 val = getMiddleValue(m_format); 604e5c31af7Sopenharmony_ci 605e5c31af7Sopenharmony_ci if (isIntegerFormat(m_format)) 606e5c31af7Sopenharmony_ci { 607e5c31af7Sopenharmony_ci colorExpr = colorBaseExpr 608e5c31af7Sopenharmony_ci + de::toString(static_cast<deInt64>(val.x())) + ", " 609e5c31af7Sopenharmony_ci + de::toString(static_cast<deInt64>(val.y())) + ", " 610e5c31af7Sopenharmony_ci + de::toString(static_cast<deInt64>(val.z())) + ", " 611e5c31af7Sopenharmony_ci + de::toString(static_cast<deInt64>(val.w())) + ")"; 612e5c31af7Sopenharmony_ci } 613e5c31af7Sopenharmony_ci else 614e5c31af7Sopenharmony_ci { 615e5c31af7Sopenharmony_ci colorExpr = colorBaseExpr 616e5c31af7Sopenharmony_ci + de::toString(val.x()) + ", " 617e5c31af7Sopenharmony_ci + de::toString(val.y()) + ", " 618e5c31af7Sopenharmony_ci + de::toString(val.z()) + ", " 619e5c31af7Sopenharmony_ci + de::toString(val.w()) + ")"; 620e5c31af7Sopenharmony_ci } 621e5c31af7Sopenharmony_ci } 622e5c31af7Sopenharmony_ci else 623e5c31af7Sopenharmony_ci { 624e5c31af7Sopenharmony_ci colorBaseExpr = colorBaseExpr 625e5c31af7Sopenharmony_ci + "gx^gy^gz, " 626e5c31af7Sopenharmony_ci + "(" + de::toString(xMax) + "-gx)^gy^gz, " 627e5c31af7Sopenharmony_ci + "gx^(" + de::toString(yMax) + "-gy)^gz, " 628e5c31af7Sopenharmony_ci + "(" + de::toString(xMax) + "-gx)^(" + de::toString(yMax) + "-gy)^gz)"; 629e5c31af7Sopenharmony_ci 630e5c31af7Sopenharmony_ci // Large integer values may not be represented with formats with low bit depths 631e5c31af7Sopenharmony_ci if (isIntegerFormat(m_format)) 632e5c31af7Sopenharmony_ci { 633e5c31af7Sopenharmony_ci const deInt64 minStoreValue = storeNegativeValues ? 0 - deRoundFloatToInt64((float)de::max(xMax, yMax) / 2.0f) : 0; 634e5c31af7Sopenharmony_ci const deInt64 maxStoreValue = storeNegativeValues ? deRoundFloatToInt64((float)de::max(xMax, yMax) / 2.0f) : de::max(xMax, yMax); 635e5c31af7Sopenharmony_ci 636e5c31af7Sopenharmony_ci useClamp = !isRepresentableIntegerValue(tcu::Vector<deInt64, 4>(minStoreValue), mapVkFormat(m_format)) || 637e5c31af7Sopenharmony_ci !isRepresentableIntegerValue(tcu::Vector<deInt64, 4>(maxStoreValue), mapVkFormat(m_format)); 638e5c31af7Sopenharmony_ci } 639e5c31af7Sopenharmony_ci 640e5c31af7Sopenharmony_ci // Clamp if integer value cannot be represented with the current format 641e5c31af7Sopenharmony_ci if (useClamp) 642e5c31af7Sopenharmony_ci { 643e5c31af7Sopenharmony_ci const tcu::IVec4 bitDepths = tcu::getTextureFormatBitDepth(mapVkFormat(m_format)); 644e5c31af7Sopenharmony_ci tcu::IVec4 minRepresentableValue; 645e5c31af7Sopenharmony_ci tcu::IVec4 maxRepresentableValue; 646e5c31af7Sopenharmony_ci 647e5c31af7Sopenharmony_ci switch (tcu::getTextureChannelClass(mapVkFormat(m_format).type)) 648e5c31af7Sopenharmony_ci { 649e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 650e5c31af7Sopenharmony_ci { 651e5c31af7Sopenharmony_ci minRepresentableValue = tcu::IVec4(0); 652e5c31af7Sopenharmony_ci maxRepresentableValue = (tcu::IVec4(1) << bitDepths) - tcu::IVec4(1); 653e5c31af7Sopenharmony_ci break; 654e5c31af7Sopenharmony_ci } 655e5c31af7Sopenharmony_ci 656e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 657e5c31af7Sopenharmony_ci { 658e5c31af7Sopenharmony_ci minRepresentableValue = -(tcu::IVec4(1) << bitDepths - tcu::IVec4(1)); 659e5c31af7Sopenharmony_ci maxRepresentableValue = (tcu::IVec4(1) << (bitDepths - tcu::IVec4(1))) - tcu::IVec4(1); 660e5c31af7Sopenharmony_ci break; 661e5c31af7Sopenharmony_ci } 662e5c31af7Sopenharmony_ci 663e5c31af7Sopenharmony_ci default: 664e5c31af7Sopenharmony_ci DE_ASSERT(isIntegerFormat(m_format)); 665e5c31af7Sopenharmony_ci } 666e5c31af7Sopenharmony_ci 667e5c31af7Sopenharmony_ci colorBaseExpr = "clamp(" + colorBaseExpr + ", " 668e5c31af7Sopenharmony_ci + signednessPrefix + "vec4" + de::toString(minRepresentableValue) + ", " 669e5c31af7Sopenharmony_ci + signednessPrefix + "vec4" + de::toString(maxRepresentableValue) + ")"; 670e5c31af7Sopenharmony_ci } 671e5c31af7Sopenharmony_ci 672e5c31af7Sopenharmony_ci colorExpr = colorBaseExpr + (storeColorScale == 1.0f ? "" : "*" + de::toString(storeColorScale)) 673e5c31af7Sopenharmony_ci + (storeColorBias == 0.0f ? "" : " + float(" + de::toString(storeColorBias) + ")"); 674e5c31af7Sopenharmony_ci 675e5c31af7Sopenharmony_ci if (storeNegativeValues) 676e5c31af7Sopenharmony_ci colorExpr += "-" + de::toString(deRoundFloatToInt32((float)deMax32(xMax, yMax) / 2.0f)); 677e5c31af7Sopenharmony_ci } 678e5c31af7Sopenharmony_ci 679e5c31af7Sopenharmony_ci const int dimension = (m_singleLayerBind ? m_texture.layerDimension() : m_texture.dimension()); 680e5c31af7Sopenharmony_ci const std::string texelCoordStr = (dimension == 1 ? "gx" : dimension == 2 ? "ivec2(gx, gy)" : dimension == 3 ? "ivec3(gx, gy, gz)" : ""); 681e5c31af7Sopenharmony_ci 682e5c31af7Sopenharmony_ci const ImageType usedImageType = (m_singleLayerBind ? getImageTypeForSingleLayer(m_texture.type()) : m_texture.type()); 683e5c31af7Sopenharmony_ci const std::string imageTypeStr = getShaderImageType(mapVkFormat(m_format), usedImageType); 684e5c31af7Sopenharmony_ci 685e5c31af7Sopenharmony_ci std::string maybeFmtQualStr = m_declareImageFormatInShader ? ", " + getShaderImageFormatQualifier(mapVkFormat(m_format)) : ""; 686e5c31af7Sopenharmony_ci 687e5c31af7Sopenharmony_ci std::ostringstream src; 688e5c31af7Sopenharmony_ci src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n" 689e5c31af7Sopenharmony_ci << "\n" 690e5c31af7Sopenharmony_ci << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 691e5c31af7Sopenharmony_ci << "layout (binding = 0" << maybeFmtQualStr << ") writeonly uniform " << imageTypeStr << " u_image;\n"; 692e5c31af7Sopenharmony_ci 693e5c31af7Sopenharmony_ci if (m_singleLayerBind) 694e5c31af7Sopenharmony_ci src << "layout (binding = 1) readonly uniform Constants {\n" 695e5c31af7Sopenharmony_ci << " int u_layerNdx;\n" 696e5c31af7Sopenharmony_ci << "};\n"; 697e5c31af7Sopenharmony_ci 698e5c31af7Sopenharmony_ci src << "\n" 699e5c31af7Sopenharmony_ci << "void main (void)\n" 700e5c31af7Sopenharmony_ci << "{\n" 701e5c31af7Sopenharmony_ci << " int gx = int(gl_GlobalInvocationID.x);\n" 702e5c31af7Sopenharmony_ci << " int gy = int(gl_GlobalInvocationID.y);\n" 703e5c31af7Sopenharmony_ci << " int gz = " << (m_singleLayerBind ? "u_layerNdx" : "int(gl_GlobalInvocationID.z)") << ";\n" 704e5c31af7Sopenharmony_ci << " " << colorType << " storedColor = " << colorExpr << ";\n" 705e5c31af7Sopenharmony_ci << " imageStore(u_image, " << texelCoordStr << ", storedColor);\n" 706e5c31af7Sopenharmony_ci << "}\n"; 707e5c31af7Sopenharmony_ci 708e5c31af7Sopenharmony_ci programCollection.glslSources.add("comp") << glu::ComputeSource(src.str()); 709e5c31af7Sopenharmony_ci} 710e5c31af7Sopenharmony_ci 711e5c31af7Sopenharmony_ci//! Generic test iteration algorithm for image tests 712e5c31af7Sopenharmony_ciclass BaseTestInstance : public TestInstance 713e5c31af7Sopenharmony_ci{ 714e5c31af7Sopenharmony_cipublic: 715e5c31af7Sopenharmony_ci BaseTestInstance (Context& context, 716e5c31af7Sopenharmony_ci const Texture& texture, 717e5c31af7Sopenharmony_ci const VkFormat format, 718e5c31af7Sopenharmony_ci const bool declareImageFormatInShader, 719e5c31af7Sopenharmony_ci const bool singleLayerBind, 720e5c31af7Sopenharmony_ci const bool minalign, 721e5c31af7Sopenharmony_ci const bool bufferLoadUniform); 722e5c31af7Sopenharmony_ci 723e5c31af7Sopenharmony_ci tcu::TestStatus iterate (void); 724e5c31af7Sopenharmony_ci 725e5c31af7Sopenharmony_ci virtual ~BaseTestInstance (void) {} 726e5c31af7Sopenharmony_ci 727e5c31af7Sopenharmony_ciprotected: 728e5c31af7Sopenharmony_ci virtual VkDescriptorSetLayout prepareDescriptors (void) = 0; 729e5c31af7Sopenharmony_ci virtual tcu::TestStatus verifyResult (void) = 0; 730e5c31af7Sopenharmony_ci 731e5c31af7Sopenharmony_ci virtual void commandBeforeCompute (const VkCommandBuffer cmdBuffer) = 0; 732e5c31af7Sopenharmony_ci virtual void commandBetweenShaderInvocations (const VkCommandBuffer cmdBuffer) = 0; 733e5c31af7Sopenharmony_ci virtual void commandAfterCompute (const VkCommandBuffer cmdBuffer) = 0; 734e5c31af7Sopenharmony_ci 735e5c31af7Sopenharmony_ci virtual void commandBindDescriptorsForLayer (const VkCommandBuffer cmdBuffer, 736e5c31af7Sopenharmony_ci const VkPipelineLayout pipelineLayout, 737e5c31af7Sopenharmony_ci const int layerNdx) = 0; 738e5c31af7Sopenharmony_ci virtual deUint32 getViewOffset (Context& context, 739e5c31af7Sopenharmony_ci const VkFormat format, 740e5c31af7Sopenharmony_ci bool uniform); 741e5c31af7Sopenharmony_ci 742e5c31af7Sopenharmony_ci const Texture m_texture; 743e5c31af7Sopenharmony_ci const VkFormat m_format; 744e5c31af7Sopenharmony_ci const bool m_declareImageFormatInShader; 745e5c31af7Sopenharmony_ci const bool m_singleLayerBind; 746e5c31af7Sopenharmony_ci const bool m_minalign; 747e5c31af7Sopenharmony_ci const bool m_bufferLoadUniform; 748e5c31af7Sopenharmony_ci const deUint32 m_srcViewOffset; 749e5c31af7Sopenharmony_ci const deUint32 m_dstViewOffset; 750e5c31af7Sopenharmony_ci}; 751e5c31af7Sopenharmony_ci 752e5c31af7Sopenharmony_ciBaseTestInstance::BaseTestInstance (Context& context, const Texture& texture, const VkFormat format, const bool declareImageFormatInShader, const bool singleLayerBind, const bool minalign, const bool bufferLoadUniform) 753e5c31af7Sopenharmony_ci : TestInstance (context) 754e5c31af7Sopenharmony_ci , m_texture (texture) 755e5c31af7Sopenharmony_ci , m_format (format) 756e5c31af7Sopenharmony_ci , m_declareImageFormatInShader (declareImageFormatInShader) 757e5c31af7Sopenharmony_ci , m_singleLayerBind (singleLayerBind) 758e5c31af7Sopenharmony_ci , m_minalign (minalign) 759e5c31af7Sopenharmony_ci , m_bufferLoadUniform (bufferLoadUniform) 760e5c31af7Sopenharmony_ci , m_srcViewOffset (getViewOffset(context, format, m_bufferLoadUniform)) 761e5c31af7Sopenharmony_ci , m_dstViewOffset (getViewOffset(context, formatHasThreeComponents(format) ? getSingleComponentFormat(format) : format, false)) 762e5c31af7Sopenharmony_ci{ 763e5c31af7Sopenharmony_ci} 764e5c31af7Sopenharmony_ci 765e5c31af7Sopenharmony_citcu::TestStatus BaseTestInstance::iterate (void) 766e5c31af7Sopenharmony_ci{ 767e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 768e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 769e5c31af7Sopenharmony_ci const VkQueue queue = m_context.getUniversalQueue(); 770e5c31af7Sopenharmony_ci const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 771e5c31af7Sopenharmony_ci 772e5c31af7Sopenharmony_ci const Unique<VkShaderModule> shaderModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0)); 773e5c31af7Sopenharmony_ci 774e5c31af7Sopenharmony_ci const VkDescriptorSetLayout descriptorSetLayout = prepareDescriptors(); 775e5c31af7Sopenharmony_ci const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device, descriptorSetLayout)); 776e5c31af7Sopenharmony_ci const Unique<VkPipeline> pipeline(makeComputePipeline(vk, device, *pipelineLayout, *shaderModule)); 777e5c31af7Sopenharmony_ci 778e5c31af7Sopenharmony_ci const Unique<VkCommandPool> cmdPool(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex)); 779e5c31af7Sopenharmony_ci const Unique<VkCommandBuffer> cmdBuffer(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 780e5c31af7Sopenharmony_ci 781e5c31af7Sopenharmony_ci beginCommandBuffer(vk, *cmdBuffer); 782e5c31af7Sopenharmony_ci 783e5c31af7Sopenharmony_ci vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline); 784e5c31af7Sopenharmony_ci commandBeforeCompute(*cmdBuffer); 785e5c31af7Sopenharmony_ci 786e5c31af7Sopenharmony_ci const tcu::IVec3 workSize = (m_singleLayerBind ? m_texture.layerSize() : m_texture.size()); 787e5c31af7Sopenharmony_ci const int loopNumLayers = (m_singleLayerBind ? m_texture.numLayers() : 1); 788e5c31af7Sopenharmony_ci for (int layerNdx = 0; layerNdx < loopNumLayers; ++layerNdx) 789e5c31af7Sopenharmony_ci { 790e5c31af7Sopenharmony_ci commandBindDescriptorsForLayer(*cmdBuffer, *pipelineLayout, layerNdx); 791e5c31af7Sopenharmony_ci 792e5c31af7Sopenharmony_ci if (layerNdx > 0) 793e5c31af7Sopenharmony_ci commandBetweenShaderInvocations(*cmdBuffer); 794e5c31af7Sopenharmony_ci 795e5c31af7Sopenharmony_ci vk.cmdDispatch(*cmdBuffer, workSize.x(), workSize.y(), workSize.z()); 796e5c31af7Sopenharmony_ci } 797e5c31af7Sopenharmony_ci 798e5c31af7Sopenharmony_ci commandAfterCompute(*cmdBuffer); 799e5c31af7Sopenharmony_ci 800e5c31af7Sopenharmony_ci endCommandBuffer(vk, *cmdBuffer); 801e5c31af7Sopenharmony_ci 802e5c31af7Sopenharmony_ci submitCommandsAndWait(vk, device, queue, *cmdBuffer); 803e5c31af7Sopenharmony_ci 804e5c31af7Sopenharmony_ci return verifyResult(); 805e5c31af7Sopenharmony_ci} 806e5c31af7Sopenharmony_ci 807e5c31af7Sopenharmony_ci//! Base store test implementation 808e5c31af7Sopenharmony_ciclass StoreTestInstance : public BaseTestInstance 809e5c31af7Sopenharmony_ci{ 810e5c31af7Sopenharmony_cipublic: 811e5c31af7Sopenharmony_ci StoreTestInstance (Context& context, 812e5c31af7Sopenharmony_ci const Texture& texture, 813e5c31af7Sopenharmony_ci const VkFormat format, 814e5c31af7Sopenharmony_ci const bool declareImageFormatInShader, 815e5c31af7Sopenharmony_ci const bool singleLayerBind, 816e5c31af7Sopenharmony_ci const bool minalign, 817e5c31af7Sopenharmony_ci const bool storeConstantValue); 818e5c31af7Sopenharmony_ci 819e5c31af7Sopenharmony_ciprotected: 820e5c31af7Sopenharmony_ci virtual tcu::TestStatus verifyResult (void); 821e5c31af7Sopenharmony_ci 822e5c31af7Sopenharmony_ci // Add empty implementations for functions that might be not needed 823e5c31af7Sopenharmony_ci void commandBeforeCompute (const VkCommandBuffer) {} 824e5c31af7Sopenharmony_ci void commandBetweenShaderInvocations (const VkCommandBuffer) {} 825e5c31af7Sopenharmony_ci void commandAfterCompute (const VkCommandBuffer) {} 826e5c31af7Sopenharmony_ci 827e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> m_imageBuffer; 828e5c31af7Sopenharmony_ci const VkDeviceSize m_imageSizeBytes; 829e5c31af7Sopenharmony_ci bool m_storeConstantValue; 830e5c31af7Sopenharmony_ci}; 831e5c31af7Sopenharmony_ci 832e5c31af7Sopenharmony_cideUint32 BaseTestInstance::getViewOffset(Context& context, 833e5c31af7Sopenharmony_ci const VkFormat format, 834e5c31af7Sopenharmony_ci bool uniform) 835e5c31af7Sopenharmony_ci{ 836e5c31af7Sopenharmony_ci if (m_minalign) 837e5c31af7Sopenharmony_ci { 838e5c31af7Sopenharmony_ci if (!context.getTexelBufferAlignmentFeaturesEXT().texelBufferAlignment) 839e5c31af7Sopenharmony_ci return (deUint32)context.getDeviceProperties().limits.minTexelBufferOffsetAlignment; 840e5c31af7Sopenharmony_ci 841e5c31af7Sopenharmony_ci VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT alignmentProperties; 842e5c31af7Sopenharmony_ci deMemset(&alignmentProperties, 0, sizeof(alignmentProperties)); 843e5c31af7Sopenharmony_ci alignmentProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT; 844e5c31af7Sopenharmony_ci 845e5c31af7Sopenharmony_ci VkPhysicalDeviceProperties2 properties2; 846e5c31af7Sopenharmony_ci deMemset(&properties2, 0, sizeof(properties2)); 847e5c31af7Sopenharmony_ci properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; 848e5c31af7Sopenharmony_ci properties2.pNext = &alignmentProperties; 849e5c31af7Sopenharmony_ci 850e5c31af7Sopenharmony_ci context.getInstanceInterface().getPhysicalDeviceProperties2(context.getPhysicalDevice(), &properties2); 851e5c31af7Sopenharmony_ci 852e5c31af7Sopenharmony_ci VkBool32 singleTexelAlignment = uniform ? alignmentProperties.uniformTexelBufferOffsetSingleTexelAlignment : 853e5c31af7Sopenharmony_ci alignmentProperties.storageTexelBufferOffsetSingleTexelAlignment; 854e5c31af7Sopenharmony_ci VkDeviceSize align = uniform ? alignmentProperties.uniformTexelBufferOffsetAlignmentBytes : 855e5c31af7Sopenharmony_ci alignmentProperties.storageTexelBufferOffsetAlignmentBytes; 856e5c31af7Sopenharmony_ci 857e5c31af7Sopenharmony_ci VkDeviceSize texelSize = formatHasThreeComponents(format) ? tcu::getChannelSize(vk::mapVkFormat(format).type) : tcu::getPixelSize(vk::mapVkFormat(format)); 858e5c31af7Sopenharmony_ci 859e5c31af7Sopenharmony_ci if (singleTexelAlignment) 860e5c31af7Sopenharmony_ci align = de::min(align, texelSize); 861e5c31af7Sopenharmony_ci 862e5c31af7Sopenharmony_ci return (deUint32)align; 863e5c31af7Sopenharmony_ci } 864e5c31af7Sopenharmony_ci 865e5c31af7Sopenharmony_ci return 0; 866e5c31af7Sopenharmony_ci} 867e5c31af7Sopenharmony_ci 868e5c31af7Sopenharmony_ciStoreTestInstance::StoreTestInstance (Context& context, const Texture& texture, const VkFormat format, const bool declareImageFormatInShader, const bool singleLayerBind, const bool minalign, const bool storeConstantValue) 869e5c31af7Sopenharmony_ci : BaseTestInstance (context, texture, format, declareImageFormatInShader, singleLayerBind, minalign, false) 870e5c31af7Sopenharmony_ci , m_imageSizeBytes (getImageSizeBytes(texture.size(), format)) 871e5c31af7Sopenharmony_ci , m_storeConstantValue (storeConstantValue) 872e5c31af7Sopenharmony_ci{ 873e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 874e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 875e5c31af7Sopenharmony_ci Allocator& allocator = m_context.getDefaultAllocator(); 876e5c31af7Sopenharmony_ci 877e5c31af7Sopenharmony_ci // A helper buffer with enough space to hold the whole image. Usage flags accommodate all derived test instances. 878e5c31af7Sopenharmony_ci 879e5c31af7Sopenharmony_ci m_imageBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory( 880e5c31af7Sopenharmony_ci vk, device, allocator, 881e5c31af7Sopenharmony_ci makeBufferCreateInfo(m_imageSizeBytes + m_dstViewOffset, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT), 882e5c31af7Sopenharmony_ci MemoryRequirement::HostVisible)); 883e5c31af7Sopenharmony_ci} 884e5c31af7Sopenharmony_ci 885e5c31af7Sopenharmony_citcu::TestStatus StoreTestInstance::verifyResult (void) 886e5c31af7Sopenharmony_ci{ 887e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 888e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 889e5c31af7Sopenharmony_ci 890e5c31af7Sopenharmony_ci const tcu::IVec3 imageSize = m_texture.size(); 891e5c31af7Sopenharmony_ci const tcu::TextureLevel reference = generateReferenceImage(imageSize, m_format, m_storeConstantValue); 892e5c31af7Sopenharmony_ci 893e5c31af7Sopenharmony_ci const Allocation& alloc = m_imageBuffer->getAllocation(); 894e5c31af7Sopenharmony_ci invalidateAlloc(vk, device, alloc); 895e5c31af7Sopenharmony_ci const tcu::ConstPixelBufferAccess result(mapVkFormat(m_format), imageSize, (const char *)alloc.getHostPtr() + m_dstViewOffset); 896e5c31af7Sopenharmony_ci 897e5c31af7Sopenharmony_ci if (comparePixelBuffers(m_context.getTestContext().getLog(), m_texture, m_format, reference.getAccess(), result)) 898e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("Passed"); 899e5c31af7Sopenharmony_ci else 900e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Image comparison failed"); 901e5c31af7Sopenharmony_ci} 902e5c31af7Sopenharmony_ci 903e5c31af7Sopenharmony_ci//! Store test for images 904e5c31af7Sopenharmony_ciclass ImageStoreTestInstance : public StoreTestInstance 905e5c31af7Sopenharmony_ci{ 906e5c31af7Sopenharmony_cipublic: 907e5c31af7Sopenharmony_ci ImageStoreTestInstance (Context& context, 908e5c31af7Sopenharmony_ci const Texture& texture, 909e5c31af7Sopenharmony_ci const VkFormat format, 910e5c31af7Sopenharmony_ci const VkImageTiling tiling, 911e5c31af7Sopenharmony_ci const bool declareImageFormatInShader, 912e5c31af7Sopenharmony_ci const bool singleLayerBind, 913e5c31af7Sopenharmony_ci const bool minalign, 914e5c31af7Sopenharmony_ci const bool storeConstantValue); 915e5c31af7Sopenharmony_ci 916e5c31af7Sopenharmony_ciprotected: 917e5c31af7Sopenharmony_ci VkDescriptorSetLayout prepareDescriptors (void); 918e5c31af7Sopenharmony_ci void commandBeforeCompute (const VkCommandBuffer cmdBuffer); 919e5c31af7Sopenharmony_ci void commandBetweenShaderInvocations (const VkCommandBuffer cmdBuffer); 920e5c31af7Sopenharmony_ci void commandAfterCompute (const VkCommandBuffer cmdBuffer); 921e5c31af7Sopenharmony_ci 922e5c31af7Sopenharmony_ci void commandBindDescriptorsForLayer (const VkCommandBuffer cmdBuffer, 923e5c31af7Sopenharmony_ci const VkPipelineLayout pipelineLayout, 924e5c31af7Sopenharmony_ci const int layerNdx); 925e5c31af7Sopenharmony_ci 926e5c31af7Sopenharmony_ci de::MovePtr<Image> m_image; 927e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> m_constantsBuffer; 928e5c31af7Sopenharmony_ci const VkDeviceSize m_constantsBufferChunkSizeBytes; 929e5c31af7Sopenharmony_ci Move<VkDescriptorSetLayout> m_descriptorSetLayout; 930e5c31af7Sopenharmony_ci Move<VkDescriptorPool> m_descriptorPool; 931e5c31af7Sopenharmony_ci std::vector<SharedVkDescriptorSet> m_allDescriptorSets; 932e5c31af7Sopenharmony_ci std::vector<SharedVkImageView> m_allImageViews; 933e5c31af7Sopenharmony_ci}; 934e5c31af7Sopenharmony_ci 935e5c31af7Sopenharmony_ciImageStoreTestInstance::ImageStoreTestInstance (Context& context, 936e5c31af7Sopenharmony_ci const Texture& texture, 937e5c31af7Sopenharmony_ci const VkFormat format, 938e5c31af7Sopenharmony_ci const VkImageTiling tiling, 939e5c31af7Sopenharmony_ci const bool declareImageFormatInShader, 940e5c31af7Sopenharmony_ci const bool singleLayerBind, 941e5c31af7Sopenharmony_ci const bool minalign, 942e5c31af7Sopenharmony_ci const bool storeConstantValue) 943e5c31af7Sopenharmony_ci : StoreTestInstance (context, texture, format, declareImageFormatInShader, singleLayerBind, minalign, storeConstantValue) 944e5c31af7Sopenharmony_ci , m_constantsBufferChunkSizeBytes (getOptimalUniformBufferChunkSize(context.getInstanceInterface(), context.getPhysicalDevice(), sizeof(deUint32))) 945e5c31af7Sopenharmony_ci , m_allDescriptorSets (texture.numLayers()) 946e5c31af7Sopenharmony_ci , m_allImageViews (texture.numLayers()) 947e5c31af7Sopenharmony_ci{ 948e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 949e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 950e5c31af7Sopenharmony_ci Allocator& allocator = m_context.getDefaultAllocator(); 951e5c31af7Sopenharmony_ci 952e5c31af7Sopenharmony_ci m_image = de::MovePtr<Image>(new Image( 953e5c31af7Sopenharmony_ci vk, device, allocator, 954e5c31af7Sopenharmony_ci makeImageCreateInfo(m_texture, m_format, (VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT), 0u, tiling), 955e5c31af7Sopenharmony_ci MemoryRequirement::Any)); 956e5c31af7Sopenharmony_ci 957e5c31af7Sopenharmony_ci // This buffer will be used to pass constants to the shader 958e5c31af7Sopenharmony_ci 959e5c31af7Sopenharmony_ci const int numLayers = m_texture.numLayers(); 960e5c31af7Sopenharmony_ci const VkDeviceSize constantsBufferSizeBytes = numLayers * m_constantsBufferChunkSizeBytes; 961e5c31af7Sopenharmony_ci m_constantsBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory( 962e5c31af7Sopenharmony_ci vk, device, allocator, 963e5c31af7Sopenharmony_ci makeBufferCreateInfo(constantsBufferSizeBytes, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT), 964e5c31af7Sopenharmony_ci MemoryRequirement::HostVisible)); 965e5c31af7Sopenharmony_ci 966e5c31af7Sopenharmony_ci { 967e5c31af7Sopenharmony_ci const Allocation& alloc = m_constantsBuffer->getAllocation(); 968e5c31af7Sopenharmony_ci deUint8* const basePtr = static_cast<deUint8*>(alloc.getHostPtr()); 969e5c31af7Sopenharmony_ci 970e5c31af7Sopenharmony_ci deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(constantsBufferSizeBytes)); 971e5c31af7Sopenharmony_ci 972e5c31af7Sopenharmony_ci for (int layerNdx = 0; layerNdx < numLayers; ++layerNdx) 973e5c31af7Sopenharmony_ci { 974e5c31af7Sopenharmony_ci deUint32* valuePtr = reinterpret_cast<deUint32*>(basePtr + layerNdx * m_constantsBufferChunkSizeBytes); 975e5c31af7Sopenharmony_ci *valuePtr = static_cast<deUint32>(layerNdx); 976e5c31af7Sopenharmony_ci } 977e5c31af7Sopenharmony_ci 978e5c31af7Sopenharmony_ci flushAlloc(vk, device, alloc); 979e5c31af7Sopenharmony_ci } 980e5c31af7Sopenharmony_ci} 981e5c31af7Sopenharmony_ci 982e5c31af7Sopenharmony_ciVkDescriptorSetLayout ImageStoreTestInstance::prepareDescriptors (void) 983e5c31af7Sopenharmony_ci{ 984e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 985e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 986e5c31af7Sopenharmony_ci 987e5c31af7Sopenharmony_ci const int numLayers = m_texture.numLayers(); 988e5c31af7Sopenharmony_ci m_descriptorSetLayout = DescriptorSetLayoutBuilder() 989e5c31af7Sopenharmony_ci .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 990e5c31af7Sopenharmony_ci .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) 991e5c31af7Sopenharmony_ci .build(vk, device); 992e5c31af7Sopenharmony_ci 993e5c31af7Sopenharmony_ci m_descriptorPool = DescriptorPoolBuilder() 994e5c31af7Sopenharmony_ci .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, numLayers) 995e5c31af7Sopenharmony_ci .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, numLayers) 996e5c31af7Sopenharmony_ci .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numLayers); 997e5c31af7Sopenharmony_ci 998e5c31af7Sopenharmony_ci if (m_singleLayerBind) 999e5c31af7Sopenharmony_ci { 1000e5c31af7Sopenharmony_ci for (int layerNdx = 0; layerNdx < numLayers; ++layerNdx) 1001e5c31af7Sopenharmony_ci { 1002e5c31af7Sopenharmony_ci m_allDescriptorSets[layerNdx] = makeVkSharedPtr(makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout)); 1003e5c31af7Sopenharmony_ci m_allImageViews[layerNdx] = makeVkSharedPtr(makeImageView( 1004e5c31af7Sopenharmony_ci vk, device, m_image->get(), mapImageViewType(getImageTypeForSingleLayer(m_texture.type())), m_format, 1005e5c31af7Sopenharmony_ci makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, layerNdx, 1u))); 1006e5c31af7Sopenharmony_ci } 1007e5c31af7Sopenharmony_ci } 1008e5c31af7Sopenharmony_ci else // bind all layers at once 1009e5c31af7Sopenharmony_ci { 1010e5c31af7Sopenharmony_ci m_allDescriptorSets[0] = makeVkSharedPtr(makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout)); 1011e5c31af7Sopenharmony_ci m_allImageViews[0] = makeVkSharedPtr(makeImageView( 1012e5c31af7Sopenharmony_ci vk, device, m_image->get(), mapImageViewType(m_texture.type()), m_format, 1013e5c31af7Sopenharmony_ci makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, numLayers))); 1014e5c31af7Sopenharmony_ci } 1015e5c31af7Sopenharmony_ci 1016e5c31af7Sopenharmony_ci return *m_descriptorSetLayout; // not passing the ownership 1017e5c31af7Sopenharmony_ci} 1018e5c31af7Sopenharmony_ci 1019e5c31af7Sopenharmony_civoid ImageStoreTestInstance::commandBindDescriptorsForLayer (const VkCommandBuffer cmdBuffer, const VkPipelineLayout pipelineLayout, const int layerNdx) 1020e5c31af7Sopenharmony_ci{ 1021e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 1022e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 1023e5c31af7Sopenharmony_ci 1024e5c31af7Sopenharmony_ci const VkDescriptorSet descriptorSet = **m_allDescriptorSets[layerNdx]; 1025e5c31af7Sopenharmony_ci const VkImageView imageView = **m_allImageViews[layerNdx]; 1026e5c31af7Sopenharmony_ci 1027e5c31af7Sopenharmony_ci const VkDescriptorImageInfo descriptorImageInfo = makeDescriptorImageInfo(DE_NULL, imageView, VK_IMAGE_LAYOUT_GENERAL); 1028e5c31af7Sopenharmony_ci 1029e5c31af7Sopenharmony_ci // Set the next chunk of the constants buffer. Each chunk begins with layer index that we've set before. 1030e5c31af7Sopenharmony_ci const VkDescriptorBufferInfo descriptorConstantsBufferInfo = makeDescriptorBufferInfo( 1031e5c31af7Sopenharmony_ci m_constantsBuffer->get(), layerNdx*m_constantsBufferChunkSizeBytes, m_constantsBufferChunkSizeBytes); 1032e5c31af7Sopenharmony_ci 1033e5c31af7Sopenharmony_ci DescriptorSetUpdateBuilder() 1034e5c31af7Sopenharmony_ci .writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo) 1035e5c31af7Sopenharmony_ci .writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &descriptorConstantsBufferInfo) 1036e5c31af7Sopenharmony_ci .update(vk, device); 1037e5c31af7Sopenharmony_ci vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL); 1038e5c31af7Sopenharmony_ci} 1039e5c31af7Sopenharmony_ci 1040e5c31af7Sopenharmony_civoid ImageStoreTestInstance::commandBeforeCompute (const VkCommandBuffer cmdBuffer) 1041e5c31af7Sopenharmony_ci{ 1042e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 1043e5c31af7Sopenharmony_ci 1044e5c31af7Sopenharmony_ci const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_texture.numLayers()); 1045e5c31af7Sopenharmony_ci const VkImageMemoryBarrier setImageLayoutBarrier = makeImageMemoryBarrier( 1046e5c31af7Sopenharmony_ci 0u, VK_ACCESS_SHADER_WRITE_BIT, 1047e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, 1048e5c31af7Sopenharmony_ci m_image->get(), fullImageSubresourceRange); 1049e5c31af7Sopenharmony_ci 1050e5c31af7Sopenharmony_ci const VkDeviceSize constantsBufferSize = m_texture.numLayers() * m_constantsBufferChunkSizeBytes; 1051e5c31af7Sopenharmony_ci const VkBufferMemoryBarrier writeConstantsBarrier = makeBufferMemoryBarrier( 1052e5c31af7Sopenharmony_ci VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, 1053e5c31af7Sopenharmony_ci m_constantsBuffer->get(), 0ull, constantsBufferSize); 1054e5c31af7Sopenharmony_ci 1055e5c31af7Sopenharmony_ci vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &writeConstantsBarrier, 1, &setImageLayoutBarrier); 1056e5c31af7Sopenharmony_ci} 1057e5c31af7Sopenharmony_ci 1058e5c31af7Sopenharmony_civoid ImageStoreTestInstance::commandBetweenShaderInvocations (const VkCommandBuffer cmdBuffer) 1059e5c31af7Sopenharmony_ci{ 1060e5c31af7Sopenharmony_ci commandImageWriteBarrierBetweenShaderInvocations(m_context, cmdBuffer, m_image->get(), m_texture); 1061e5c31af7Sopenharmony_ci} 1062e5c31af7Sopenharmony_ci 1063e5c31af7Sopenharmony_civoid ImageStoreTestInstance::commandAfterCompute (const VkCommandBuffer cmdBuffer) 1064e5c31af7Sopenharmony_ci{ 1065e5c31af7Sopenharmony_ci commandCopyImageToBuffer(m_context, cmdBuffer, m_image->get(), m_imageBuffer->get(), m_imageSizeBytes, m_texture); 1066e5c31af7Sopenharmony_ci} 1067e5c31af7Sopenharmony_ci 1068e5c31af7Sopenharmony_ci//! Store test for buffers 1069e5c31af7Sopenharmony_ciclass BufferStoreTestInstance : public StoreTestInstance 1070e5c31af7Sopenharmony_ci{ 1071e5c31af7Sopenharmony_cipublic: 1072e5c31af7Sopenharmony_ci BufferStoreTestInstance (Context& context, 1073e5c31af7Sopenharmony_ci const Texture& texture, 1074e5c31af7Sopenharmony_ci const VkFormat format, 1075e5c31af7Sopenharmony_ci const bool declareImageFormatInShader, 1076e5c31af7Sopenharmony_ci const bool minalign, 1077e5c31af7Sopenharmony_ci const bool storeConstantValue); 1078e5c31af7Sopenharmony_ci 1079e5c31af7Sopenharmony_ciprotected: 1080e5c31af7Sopenharmony_ci VkDescriptorSetLayout prepareDescriptors (void); 1081e5c31af7Sopenharmony_ci void commandAfterCompute (const VkCommandBuffer cmdBuffer); 1082e5c31af7Sopenharmony_ci 1083e5c31af7Sopenharmony_ci void commandBindDescriptorsForLayer (const VkCommandBuffer cmdBuffer, 1084e5c31af7Sopenharmony_ci const VkPipelineLayout pipelineLayout, 1085e5c31af7Sopenharmony_ci const int layerNdx); 1086e5c31af7Sopenharmony_ci 1087e5c31af7Sopenharmony_ci Move<VkDescriptorSetLayout> m_descriptorSetLayout; 1088e5c31af7Sopenharmony_ci Move<VkDescriptorPool> m_descriptorPool; 1089e5c31af7Sopenharmony_ci Move<VkDescriptorSet> m_descriptorSet; 1090e5c31af7Sopenharmony_ci Move<VkBufferView> m_bufferView; 1091e5c31af7Sopenharmony_ci}; 1092e5c31af7Sopenharmony_ci 1093e5c31af7Sopenharmony_ciBufferStoreTestInstance::BufferStoreTestInstance (Context& context, 1094e5c31af7Sopenharmony_ci const Texture& texture, 1095e5c31af7Sopenharmony_ci const VkFormat format, 1096e5c31af7Sopenharmony_ci const bool declareImageFormatInShader, 1097e5c31af7Sopenharmony_ci const bool minalign, 1098e5c31af7Sopenharmony_ci const bool storeConstantValue) 1099e5c31af7Sopenharmony_ci : StoreTestInstance(context, texture, format, declareImageFormatInShader, false, minalign, storeConstantValue) 1100e5c31af7Sopenharmony_ci{ 1101e5c31af7Sopenharmony_ci} 1102e5c31af7Sopenharmony_ci 1103e5c31af7Sopenharmony_ciVkDescriptorSetLayout BufferStoreTestInstance::prepareDescriptors (void) 1104e5c31af7Sopenharmony_ci{ 1105e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 1106e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 1107e5c31af7Sopenharmony_ci 1108e5c31af7Sopenharmony_ci m_descriptorSetLayout = DescriptorSetLayoutBuilder() 1109e5c31af7Sopenharmony_ci .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) 1110e5c31af7Sopenharmony_ci .build(vk, device); 1111e5c31af7Sopenharmony_ci 1112e5c31af7Sopenharmony_ci m_descriptorPool = DescriptorPoolBuilder() 1113e5c31af7Sopenharmony_ci .addType(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) 1114e5c31af7Sopenharmony_ci .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 1115e5c31af7Sopenharmony_ci 1116e5c31af7Sopenharmony_ci m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout); 1117e5c31af7Sopenharmony_ci m_bufferView = makeBufferView(vk, device, m_imageBuffer->get(), m_format, m_dstViewOffset, m_imageSizeBytes); 1118e5c31af7Sopenharmony_ci 1119e5c31af7Sopenharmony_ci return *m_descriptorSetLayout; // not passing the ownership 1120e5c31af7Sopenharmony_ci} 1121e5c31af7Sopenharmony_ci 1122e5c31af7Sopenharmony_civoid BufferStoreTestInstance::commandBindDescriptorsForLayer (const VkCommandBuffer cmdBuffer, const VkPipelineLayout pipelineLayout, const int layerNdx) 1123e5c31af7Sopenharmony_ci{ 1124e5c31af7Sopenharmony_ci DE_ASSERT(layerNdx == 0); 1125e5c31af7Sopenharmony_ci DE_UNREF(layerNdx); 1126e5c31af7Sopenharmony_ci 1127e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 1128e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 1129e5c31af7Sopenharmony_ci 1130e5c31af7Sopenharmony_ci DescriptorSetUpdateBuilder() 1131e5c31af7Sopenharmony_ci .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, &m_bufferView.get()) 1132e5c31af7Sopenharmony_ci .update(vk, device); 1133e5c31af7Sopenharmony_ci vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL); 1134e5c31af7Sopenharmony_ci} 1135e5c31af7Sopenharmony_ci 1136e5c31af7Sopenharmony_civoid BufferStoreTestInstance::commandAfterCompute (const VkCommandBuffer cmdBuffer) 1137e5c31af7Sopenharmony_ci{ 1138e5c31af7Sopenharmony_ci commandBufferWriteBarrierBeforeHostRead(m_context, cmdBuffer, m_imageBuffer->get(), m_imageSizeBytes + m_dstViewOffset); 1139e5c31af7Sopenharmony_ci} 1140e5c31af7Sopenharmony_ci 1141e5c31af7Sopenharmony_ciclass LoadStoreTest : public TestCase 1142e5c31af7Sopenharmony_ci{ 1143e5c31af7Sopenharmony_cipublic: 1144e5c31af7Sopenharmony_ci enum TestFlags 1145e5c31af7Sopenharmony_ci { 1146e5c31af7Sopenharmony_ci FLAG_SINGLE_LAYER_BIND = (1 << 0), //!< Run the shader multiple times, each time binding a different layer. 1147e5c31af7Sopenharmony_ci FLAG_RESTRICT_IMAGES = (1 << 1), //!< If given, images in the shader will be qualified with "restrict". 1148e5c31af7Sopenharmony_ci FLAG_DECLARE_FORMAT_IN_SHADER_READS = (1 << 2), //!< Declare the format of images being read in the shader code 1149e5c31af7Sopenharmony_ci FLAG_DECLARE_FORMAT_IN_SHADER_WRITES = (1 << 3), //!< Declare the format of images being read in the shader code 1150e5c31af7Sopenharmony_ci FLAG_MINALIGN = (1 << 4), //!< Use bufferview offset that matches the advertised minimum alignment 1151e5c31af7Sopenharmony_ci FLAG_UNIFORM_TEXEL_BUFFER = (1 << 5), //!< Load from a uniform texel buffer rather than a storage texel buffer 1152e5c31af7Sopenharmony_ci }; 1153e5c31af7Sopenharmony_ci 1154e5c31af7Sopenharmony_ci LoadStoreTest (tcu::TestContext& testCtx, 1155e5c31af7Sopenharmony_ci const std::string& name, 1156e5c31af7Sopenharmony_ci const Texture& texture, 1157e5c31af7Sopenharmony_ci const VkFormat format, 1158e5c31af7Sopenharmony_ci const VkFormat imageFormat, 1159e5c31af7Sopenharmony_ci const VkImageTiling tiling, 1160e5c31af7Sopenharmony_ci const deUint32 flags = (FLAG_DECLARE_FORMAT_IN_SHADER_READS | FLAG_DECLARE_FORMAT_IN_SHADER_WRITES), 1161e5c31af7Sopenharmony_ci const deBool imageLoadStoreLodAMD = DE_FALSE); 1162e5c31af7Sopenharmony_ci 1163e5c31af7Sopenharmony_ci virtual void checkSupport (Context& context) const; 1164e5c31af7Sopenharmony_ci void initPrograms (SourceCollections& programCollection) const; 1165e5c31af7Sopenharmony_ci TestInstance* createInstance (Context& context) const; 1166e5c31af7Sopenharmony_ci 1167e5c31af7Sopenharmony_ciprivate: 1168e5c31af7Sopenharmony_ci const Texture m_texture; 1169e5c31af7Sopenharmony_ci const VkFormat m_format; //!< Format as accessed in the shader 1170e5c31af7Sopenharmony_ci const VkFormat m_imageFormat; //!< Storage format 1171e5c31af7Sopenharmony_ci const VkImageTiling m_tiling; //!< Image Tiling 1172e5c31af7Sopenharmony_ci const bool m_declareFormatInShaderReads; //!< Whether the shader will specify the format layout qualifier of images being read from. 1173e5c31af7Sopenharmony_ci const bool m_declareFormatInShaderWrites; //!< Whether the shader will specify the format layout qualifier of images being written to. 1174e5c31af7Sopenharmony_ci const bool m_singleLayerBind; 1175e5c31af7Sopenharmony_ci const bool m_restrictImages; 1176e5c31af7Sopenharmony_ci const bool m_minalign; 1177e5c31af7Sopenharmony_ci bool m_bufferLoadUniform; 1178e5c31af7Sopenharmony_ci const deBool m_imageLoadStoreLodAMD; 1179e5c31af7Sopenharmony_ci}; 1180e5c31af7Sopenharmony_ci 1181e5c31af7Sopenharmony_ciLoadStoreTest::LoadStoreTest (tcu::TestContext& testCtx, 1182e5c31af7Sopenharmony_ci const std::string& name, 1183e5c31af7Sopenharmony_ci const Texture& texture, 1184e5c31af7Sopenharmony_ci const VkFormat format, 1185e5c31af7Sopenharmony_ci const VkFormat imageFormat, 1186e5c31af7Sopenharmony_ci const VkImageTiling tiling, 1187e5c31af7Sopenharmony_ci const deUint32 flags, 1188e5c31af7Sopenharmony_ci const deBool imageLoadStoreLodAMD) 1189e5c31af7Sopenharmony_ci : TestCase (testCtx, name) 1190e5c31af7Sopenharmony_ci , m_texture (texture) 1191e5c31af7Sopenharmony_ci , m_format (format) 1192e5c31af7Sopenharmony_ci , m_imageFormat (imageFormat) 1193e5c31af7Sopenharmony_ci , m_tiling (tiling) 1194e5c31af7Sopenharmony_ci , m_declareFormatInShaderReads ((flags & FLAG_DECLARE_FORMAT_IN_SHADER_READS) != 0) 1195e5c31af7Sopenharmony_ci , m_declareFormatInShaderWrites ((flags & FLAG_DECLARE_FORMAT_IN_SHADER_WRITES) != 0) 1196e5c31af7Sopenharmony_ci , m_singleLayerBind ((flags & FLAG_SINGLE_LAYER_BIND) != 0) 1197e5c31af7Sopenharmony_ci , m_restrictImages ((flags & FLAG_RESTRICT_IMAGES) != 0) 1198e5c31af7Sopenharmony_ci , m_minalign ((flags & FLAG_MINALIGN) != 0) 1199e5c31af7Sopenharmony_ci , m_bufferLoadUniform ((flags & FLAG_UNIFORM_TEXEL_BUFFER) != 0) 1200e5c31af7Sopenharmony_ci , m_imageLoadStoreLodAMD (imageLoadStoreLodAMD) 1201e5c31af7Sopenharmony_ci{ 1202e5c31af7Sopenharmony_ci if (m_singleLayerBind) 1203e5c31af7Sopenharmony_ci DE_ASSERT(m_texture.numLayers() > 1); 1204e5c31af7Sopenharmony_ci 1205e5c31af7Sopenharmony_ci DE_ASSERT(formatsAreCompatible(m_format, m_imageFormat)); 1206e5c31af7Sopenharmony_ci} 1207e5c31af7Sopenharmony_ci 1208e5c31af7Sopenharmony_civoid LoadStoreTest::checkSupport (Context& context) const 1209e5c31af7Sopenharmony_ci{ 1210e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 1211e5c31af7Sopenharmony_ci if (m_format == VK_FORMAT_A8_UNORM_KHR || m_format == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR) 1212e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_KHR_maintenance5"); 1213e5c31af7Sopenharmony_ci 1214e5c31af7Sopenharmony_ci const VkFormatProperties3 formatProperties (context.getFormatProperties(m_format)); 1215e5c31af7Sopenharmony_ci const VkFormatProperties3 imageFormatProperties (context.getFormatProperties(m_imageFormat)); 1216e5c31af7Sopenharmony_ci 1217e5c31af7Sopenharmony_ci const auto& tilingFeatures = (m_tiling == vk::VK_IMAGE_TILING_OPTIMAL) ? formatProperties.optimalTilingFeatures : formatProperties.linearTilingFeatures; 1218e5c31af7Sopenharmony_ci const auto& imageTilingFeatures = (m_tiling == vk::VK_IMAGE_TILING_OPTIMAL) ? imageFormatProperties.optimalTilingFeatures : imageFormatProperties.linearTilingFeatures; 1219e5c31af7Sopenharmony_ci 1220e5c31af7Sopenharmony_ci if (m_imageLoadStoreLodAMD) 1221e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_AMD_shader_image_load_store_lod"); 1222e5c31af7Sopenharmony_ci 1223e5c31af7Sopenharmony_ci if (!m_bufferLoadUniform && !m_declareFormatInShaderReads && !(tilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT)) 1224e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for unformatted loads via storage images"); 1225e5c31af7Sopenharmony_ci 1226e5c31af7Sopenharmony_ci if (m_texture.type() == IMAGE_TYPE_BUFFER && !m_declareFormatInShaderReads && !(formatProperties.bufferFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT)) 1227e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for unformatted loads via buffers"); 1228e5c31af7Sopenharmony_ci 1229e5c31af7Sopenharmony_ci if (!m_declareFormatInShaderWrites && !(tilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT)) 1230e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for unformatted stores via storage images"); 1231e5c31af7Sopenharmony_ci 1232e5c31af7Sopenharmony_ci if (m_texture.type() == IMAGE_TYPE_BUFFER && !m_declareFormatInShaderWrites && !(formatProperties.bufferFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT)) 1233e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for unformatted stores via buffers"); 1234e5c31af7Sopenharmony_ci 1235e5c31af7Sopenharmony_ci if (m_texture.type() == IMAGE_TYPE_CUBE_ARRAY) 1236e5c31af7Sopenharmony_ci context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY); 1237e5c31af7Sopenharmony_ci 1238e5c31af7Sopenharmony_ci if ((m_texture.type() != IMAGE_TYPE_BUFFER) && !(tilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) 1239e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for storage images"); 1240e5c31af7Sopenharmony_ci 1241e5c31af7Sopenharmony_ci if ((m_texture.type() != IMAGE_TYPE_BUFFER) && !(imageTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) 1242e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for storage images"); 1243e5c31af7Sopenharmony_ci 1244e5c31af7Sopenharmony_ci if (m_texture.type() == IMAGE_TYPE_BUFFER && !(formatProperties.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)) 1245e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for storage texel buffers"); 1246e5c31af7Sopenharmony_ci 1247e5c31af7Sopenharmony_ci if ((m_texture.type() != IMAGE_TYPE_BUFFER) && !(imageTilingFeatures)) 1248e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Underlying format not supported at all for images"); 1249e5c31af7Sopenharmony_ci 1250e5c31af7Sopenharmony_ci if ((m_texture.type() == IMAGE_TYPE_BUFFER) && !(imageFormatProperties.bufferFeatures)) 1251e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Underlying format not supported at all for buffers"); 1252e5c31af7Sopenharmony_ci 1253e5c31af7Sopenharmony_ci if (formatHasThreeComponents(m_format)) 1254e5c31af7Sopenharmony_ci { 1255e5c31af7Sopenharmony_ci // When the source buffer is three-component, the destination buffer is single-component. 1256e5c31af7Sopenharmony_ci VkFormat dstFormat = getSingleComponentFormat(m_format); 1257e5c31af7Sopenharmony_ci const VkFormatProperties3 dstFormatProperties (context.getFormatProperties(dstFormat)); 1258e5c31af7Sopenharmony_ci 1259e5c31af7Sopenharmony_ci if (m_texture.type() == IMAGE_TYPE_BUFFER && !(dstFormatProperties.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)) 1260e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for storage texel buffers"); 1261e5c31af7Sopenharmony_ci } 1262e5c31af7Sopenharmony_ci else 1263e5c31af7Sopenharmony_ci if (m_texture.type() == IMAGE_TYPE_BUFFER && !(formatProperties.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)) 1264e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for storage texel buffers"); 1265e5c31af7Sopenharmony_ci 1266e5c31af7Sopenharmony_ci if (m_bufferLoadUniform && m_texture.type() == IMAGE_TYPE_BUFFER && !(formatProperties.bufferFeatures & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)) 1267e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for uniform texel buffers"); 1268e5c31af7Sopenharmony_ci#else 1269e5c31af7Sopenharmony_ci const vk::VkFormatProperties formatProperties (vk::getPhysicalDeviceFormatProperties(context.getInstanceInterface(), 1270e5c31af7Sopenharmony_ci context.getPhysicalDevice(), 1271e5c31af7Sopenharmony_ci m_format)); 1272e5c31af7Sopenharmony_ci const vk::VkFormatProperties imageFormatProperties (vk::getPhysicalDeviceFormatProperties(context.getInstanceInterface(), 1273e5c31af7Sopenharmony_ci context.getPhysicalDevice(), 1274e5c31af7Sopenharmony_ci m_imageFormat)); 1275e5c31af7Sopenharmony_ci 1276e5c31af7Sopenharmony_ci const auto tilingFeatures = (m_tiling == vk::VK_IMAGE_TILING_OPTIMAL) ? formatProperties.optimalTilingFeatures : formatProperties.linearTilingFeatures; 1277e5c31af7Sopenharmony_ci const auto imageTilingFeatures = (m_tiling == vk::VK_IMAGE_TILING_OPTIMAL) ? imageFormatProperties.optimalTilingFeatures : imageFormatProperties.linearTilingFeatures; 1278e5c31af7Sopenharmony_ci 1279e5c31af7Sopenharmony_ci if (m_imageLoadStoreLodAMD) 1280e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_AMD_shader_image_load_store_lod"); 1281e5c31af7Sopenharmony_ci 1282e5c31af7Sopenharmony_ci if (!m_bufferLoadUniform && !m_declareFormatInShaderReads) 1283e5c31af7Sopenharmony_ci context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT); 1284e5c31af7Sopenharmony_ci 1285e5c31af7Sopenharmony_ci if (!m_declareFormatInShaderWrites) 1286e5c31af7Sopenharmony_ci context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT); 1287e5c31af7Sopenharmony_ci 1288e5c31af7Sopenharmony_ci if (m_texture.type() == IMAGE_TYPE_CUBE_ARRAY) 1289e5c31af7Sopenharmony_ci context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY); 1290e5c31af7Sopenharmony_ci 1291e5c31af7Sopenharmony_ci if ((m_texture.type() != IMAGE_TYPE_BUFFER) && !(tilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) 1292e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for storage images"); 1293e5c31af7Sopenharmony_ci 1294e5c31af7Sopenharmony_ci if ((m_texture.type() != IMAGE_TYPE_BUFFER) && !(imageTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) 1295e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for storage images"); 1296e5c31af7Sopenharmony_ci 1297e5c31af7Sopenharmony_ci if (m_texture.type() == IMAGE_TYPE_BUFFER && !(formatProperties.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)) 1298e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for storage texel buffers"); 1299e5c31af7Sopenharmony_ci 1300e5c31af7Sopenharmony_ci if ((m_texture.type() != IMAGE_TYPE_BUFFER) && !(imageTilingFeatures)) 1301e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Underlying format not supported at all for images"); 1302e5c31af7Sopenharmony_ci 1303e5c31af7Sopenharmony_ci if ((m_texture.type() == IMAGE_TYPE_BUFFER) && !(imageFormatProperties.bufferFeatures)) 1304e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Underlying format not supported at all for buffers"); 1305e5c31af7Sopenharmony_ci 1306e5c31af7Sopenharmony_ci if (formatHasThreeComponents(m_format)) 1307e5c31af7Sopenharmony_ci { 1308e5c31af7Sopenharmony_ci // When the source buffer is three-component, the destination buffer is single-component. 1309e5c31af7Sopenharmony_ci VkFormat dstFormat = getSingleComponentFormat(m_format); 1310e5c31af7Sopenharmony_ci const vk::VkFormatProperties dstFormatProperties (vk::getPhysicalDeviceFormatProperties(context.getInstanceInterface(), 1311e5c31af7Sopenharmony_ci context.getPhysicalDevice(), 1312e5c31af7Sopenharmony_ci dstFormat)); 1313e5c31af7Sopenharmony_ci 1314e5c31af7Sopenharmony_ci if (m_texture.type() == IMAGE_TYPE_BUFFER && !(dstFormatProperties.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)) 1315e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for storage texel buffers"); 1316e5c31af7Sopenharmony_ci } 1317e5c31af7Sopenharmony_ci else 1318e5c31af7Sopenharmony_ci if (m_texture.type() == IMAGE_TYPE_BUFFER && !(formatProperties.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)) 1319e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for storage texel buffers"); 1320e5c31af7Sopenharmony_ci 1321e5c31af7Sopenharmony_ci if (m_bufferLoadUniform && m_texture.type() == IMAGE_TYPE_BUFFER && !(formatProperties.bufferFeatures & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)) 1322e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for uniform texel buffers"); 1323e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 1324e5c31af7Sopenharmony_ci 1325e5c31af7Sopenharmony_ci const auto& vki = context.getInstanceInterface(); 1326e5c31af7Sopenharmony_ci const auto physicalDevice = context.getPhysicalDevice(); 1327e5c31af7Sopenharmony_ci 1328e5c31af7Sopenharmony_ci VkImageFormatProperties vkImageFormatProperties; 1329e5c31af7Sopenharmony_ci const auto result = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, m_imageFormat, mapImageType(m_texture.type()), m_tiling, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0, &vkImageFormatProperties); 1330e5c31af7Sopenharmony_ci 1331e5c31af7Sopenharmony_ci if (result != VK_SUCCESS) 1332e5c31af7Sopenharmony_ci { 1333e5c31af7Sopenharmony_ci if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) 1334e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format unsupported for tiling"); 1335e5c31af7Sopenharmony_ci else 1336e5c31af7Sopenharmony_ci TCU_FAIL("vkGetPhysicalDeviceImageFormatProperties returned unexpected error"); 1337e5c31af7Sopenharmony_ci } 1338e5c31af7Sopenharmony_ci 1339e5c31af7Sopenharmony_ci if (vkImageFormatProperties.maxArrayLayers < (uint32_t)m_texture.numLayers()) { 1340e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "This format and tiling combination does not support this number of aray layers"); 1341e5c31af7Sopenharmony_ci } 1342e5c31af7Sopenharmony_ci 1343e5c31af7Sopenharmony_ci if (vkImageFormatProperties.maxMipLevels < (uint32_t)m_texture.numMipmapLevels()) { 1344e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "This format and tiling combination does not support this number of miplevels"); 1345e5c31af7Sopenharmony_ci } 1346e5c31af7Sopenharmony_ci} 1347e5c31af7Sopenharmony_ci 1348e5c31af7Sopenharmony_civoid LoadStoreTest::initPrograms (SourceCollections& programCollection) const 1349e5c31af7Sopenharmony_ci{ 1350e5c31af7Sopenharmony_ci const tcu::TextureFormat texFormat = mapVkFormat(m_format); 1351e5c31af7Sopenharmony_ci const int dimension = (m_singleLayerBind ? m_texture.layerDimension() : m_texture.dimension()); 1352e5c31af7Sopenharmony_ci const ImageType usedImageType = (m_singleLayerBind ? getImageTypeForSingleLayer(m_texture.type()) : m_texture.type()); 1353e5c31af7Sopenharmony_ci const bool noFormats = (!m_declareFormatInShaderReads && !m_declareFormatInShaderWrites); 1354e5c31af7Sopenharmony_ci const std::string formatQualifierStr = (noFormats ? "" : getShaderImageFormatQualifier(texFormat)); 1355e5c31af7Sopenharmony_ci const std::string uniformTypeStr = getFormatPrefix(texFormat) + "textureBuffer"; 1356e5c31af7Sopenharmony_ci const std::string imageTypeStr = getShaderImageType(texFormat, usedImageType); 1357e5c31af7Sopenharmony_ci const std::string maybeRestrictStr = (m_restrictImages ? "restrict " : ""); 1358e5c31af7Sopenharmony_ci const std::string xMax = de::toString(m_texture.size().x() - 1); 1359e5c31af7Sopenharmony_ci 1360e5c31af7Sopenharmony_ci std::ostringstream src; 1361e5c31af7Sopenharmony_ci src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n" 1362e5c31af7Sopenharmony_ci << "\n"; 1363e5c31af7Sopenharmony_ci 1364e5c31af7Sopenharmony_ci if (!m_declareFormatInShaderReads || !m_declareFormatInShaderWrites) 1365e5c31af7Sopenharmony_ci { 1366e5c31af7Sopenharmony_ci src << "#extension GL_EXT_shader_image_load_formatted : require\n"; 1367e5c31af7Sopenharmony_ci } 1368e5c31af7Sopenharmony_ci 1369e5c31af7Sopenharmony_ci if (m_imageLoadStoreLodAMD) 1370e5c31af7Sopenharmony_ci { 1371e5c31af7Sopenharmony_ci src << "#extension GL_AMD_shader_image_load_store_lod : require\n"; 1372e5c31af7Sopenharmony_ci } 1373e5c31af7Sopenharmony_ci 1374e5c31af7Sopenharmony_ci const std::string maybeFmtQualStrReads = m_declareFormatInShaderReads ? ", " + formatQualifierStr : ""; 1375e5c31af7Sopenharmony_ci const std::string maybeFmtQualStrWrites = m_declareFormatInShaderWrites ? ", " + formatQualifierStr : ""; 1376e5c31af7Sopenharmony_ci 1377e5c31af7Sopenharmony_ci src << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"; 1378e5c31af7Sopenharmony_ci 1379e5c31af7Sopenharmony_ci if (m_bufferLoadUniform) 1380e5c31af7Sopenharmony_ci src << "layout (binding = 0) uniform " << uniformTypeStr << " u_image0;\n"; 1381e5c31af7Sopenharmony_ci else 1382e5c31af7Sopenharmony_ci src << "layout (binding = 0" << maybeFmtQualStrReads << ") " << maybeRestrictStr << "readonly uniform " << imageTypeStr << " u_image0;\n"; 1383e5c31af7Sopenharmony_ci 1384e5c31af7Sopenharmony_ci // For three-component formats, the dst buffer is single-component and the shader expands the store into 3 component-wise stores. 1385e5c31af7Sopenharmony_ci // We always use the format qualifier for the dst buffer, except when splitting it up. 1386e5c31af7Sopenharmony_ci if (formatHasThreeComponents(m_format)) 1387e5c31af7Sopenharmony_ci src << "layout (binding = 1) " << maybeRestrictStr << "writeonly uniform " << imageTypeStr << " u_image1;\n"; 1388e5c31af7Sopenharmony_ci else 1389e5c31af7Sopenharmony_ci src << "layout (binding = 1" << maybeFmtQualStrWrites << ") " << maybeRestrictStr << "writeonly uniform " << imageTypeStr << " u_image1;\n"; 1390e5c31af7Sopenharmony_ci 1391e5c31af7Sopenharmony_ci src << "\n" 1392e5c31af7Sopenharmony_ci << "void main (void)\n" 1393e5c31af7Sopenharmony_ci << "{\n"; 1394e5c31af7Sopenharmony_ci 1395e5c31af7Sopenharmony_ci switch (dimension) 1396e5c31af7Sopenharmony_ci { 1397e5c31af7Sopenharmony_ci default: DE_ASSERT(0); // fallthrough 1398e5c31af7Sopenharmony_ci case 1: 1399e5c31af7Sopenharmony_ci if (m_bufferLoadUniform) 1400e5c31af7Sopenharmony_ci { 1401e5c31af7Sopenharmony_ci // Expand the store into 3 component-wise stores. 1402e5c31af7Sopenharmony_ci std::string type = getFormatPrefix(texFormat) + "vec4"; 1403e5c31af7Sopenharmony_ci src << " int pos = int(gl_GlobalInvocationID.x);\n" 1404e5c31af7Sopenharmony_ci " " << type << " t = texelFetch(u_image0, " + xMax + "-pos);\n"; 1405e5c31af7Sopenharmony_ci if (formatHasThreeComponents(m_format)) 1406e5c31af7Sopenharmony_ci { 1407e5c31af7Sopenharmony_ci src << " imageStore(u_image1, 3*pos+0, " << type << "(t.x));\n"; 1408e5c31af7Sopenharmony_ci src << " imageStore(u_image1, 3*pos+1, " << type << "(t.y));\n"; 1409e5c31af7Sopenharmony_ci src << " imageStore(u_image1, 3*pos+2, " << type << "(t.z));\n"; 1410e5c31af7Sopenharmony_ci } 1411e5c31af7Sopenharmony_ci else 1412e5c31af7Sopenharmony_ci src << " imageStore(u_image1, pos, t);\n"; 1413e5c31af7Sopenharmony_ci } 1414e5c31af7Sopenharmony_ci else if (m_imageLoadStoreLodAMD) 1415e5c31af7Sopenharmony_ci { 1416e5c31af7Sopenharmony_ci src << 1417e5c31af7Sopenharmony_ci " int pos = int(gl_GlobalInvocationID.x);\n"; 1418e5c31af7Sopenharmony_ci 1419e5c31af7Sopenharmony_ci for (deInt32 levelNdx = 0; levelNdx < m_texture.numMipmapLevels(); levelNdx++) 1420e5c31af7Sopenharmony_ci { 1421e5c31af7Sopenharmony_ci std::string xMaxSize = de::toString(deMax32(((m_texture.layerSize().x() >> levelNdx) - 1), 1u)); 1422e5c31af7Sopenharmony_ci src << " imageStoreLodAMD(u_image1, pos, " + de::toString(levelNdx) + ", imageLoadLodAMD(u_image0, " + xMaxSize + "-pos, " + de::toString(levelNdx) + "));\n"; 1423e5c31af7Sopenharmony_ci } 1424e5c31af7Sopenharmony_ci } 1425e5c31af7Sopenharmony_ci else 1426e5c31af7Sopenharmony_ci { 1427e5c31af7Sopenharmony_ci src << 1428e5c31af7Sopenharmony_ci " int pos = int(gl_GlobalInvocationID.x);\n" 1429e5c31af7Sopenharmony_ci " imageStore(u_image1, pos, imageLoad(u_image0, " + xMax + "-pos));\n"; 1430e5c31af7Sopenharmony_ci } 1431e5c31af7Sopenharmony_ci break; 1432e5c31af7Sopenharmony_ci case 2: 1433e5c31af7Sopenharmony_ci if (m_imageLoadStoreLodAMD) 1434e5c31af7Sopenharmony_ci { 1435e5c31af7Sopenharmony_ci src << " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n"; 1436e5c31af7Sopenharmony_ci 1437e5c31af7Sopenharmony_ci for (deInt32 levelNdx = 0; levelNdx < m_texture.numMipmapLevels(); levelNdx++) 1438e5c31af7Sopenharmony_ci { 1439e5c31af7Sopenharmony_ci std::string xMaxSize = de::toString(deMax32(((m_texture.layerSize().x() >> levelNdx) - 1), 1u)); 1440e5c31af7Sopenharmony_ci src << " imageStoreLodAMD(u_image1, pos, " + de::toString(levelNdx) + ", imageLoadLodAMD(u_image0, ivec2(" + xMaxSize + "-pos.x, pos.y), " + de::toString(levelNdx) + "));\n"; 1441e5c31af7Sopenharmony_ci } 1442e5c31af7Sopenharmony_ci 1443e5c31af7Sopenharmony_ci } 1444e5c31af7Sopenharmony_ci else 1445e5c31af7Sopenharmony_ci { 1446e5c31af7Sopenharmony_ci src << 1447e5c31af7Sopenharmony_ci " ivec2 pos = ivec2(gl_GlobalInvocationID.xy);\n" 1448e5c31af7Sopenharmony_ci " imageStore(u_image1, pos, imageLoad(u_image0, ivec2(" + xMax + "-pos.x, pos.y)));\n"; 1449e5c31af7Sopenharmony_ci } 1450e5c31af7Sopenharmony_ci break; 1451e5c31af7Sopenharmony_ci case 3: 1452e5c31af7Sopenharmony_ci if (m_imageLoadStoreLodAMD) 1453e5c31af7Sopenharmony_ci { 1454e5c31af7Sopenharmony_ci src << " ivec3 pos = ivec3(gl_GlobalInvocationID);\n"; 1455e5c31af7Sopenharmony_ci 1456e5c31af7Sopenharmony_ci for (deInt32 levelNdx = 0; levelNdx < m_texture.numMipmapLevels(); levelNdx++) 1457e5c31af7Sopenharmony_ci { 1458e5c31af7Sopenharmony_ci std::string xMaxSize = de::toString(deMax32(((m_texture.layerSize().x() >> levelNdx) - 1), 1u)); 1459e5c31af7Sopenharmony_ci src << " imageStoreLodAMD(u_image1, pos, " + de::toString(levelNdx) + ", imageLoadLodAMD(u_image0, ivec3(" + xMaxSize + "-pos.x, pos.y, pos.z), " + de::toString(levelNdx) + "));\n"; 1460e5c31af7Sopenharmony_ci } 1461e5c31af7Sopenharmony_ci } 1462e5c31af7Sopenharmony_ci else 1463e5c31af7Sopenharmony_ci { 1464e5c31af7Sopenharmony_ci src << 1465e5c31af7Sopenharmony_ci " ivec3 pos = ivec3(gl_GlobalInvocationID);\n" 1466e5c31af7Sopenharmony_ci " imageStore(u_image1, pos, imageLoad(u_image0, ivec3(" + xMax + "-pos.x, pos.y, pos.z)));\n"; 1467e5c31af7Sopenharmony_ci } 1468e5c31af7Sopenharmony_ci break; 1469e5c31af7Sopenharmony_ci } 1470e5c31af7Sopenharmony_ci src << "}\n"; 1471e5c31af7Sopenharmony_ci 1472e5c31af7Sopenharmony_ci programCollection.glslSources.add("comp") << glu::ComputeSource(src.str()); 1473e5c31af7Sopenharmony_ci} 1474e5c31af7Sopenharmony_ci 1475e5c31af7Sopenharmony_ci//! Load/store test base implementation 1476e5c31af7Sopenharmony_ciclass LoadStoreTestInstance : public BaseTestInstance 1477e5c31af7Sopenharmony_ci{ 1478e5c31af7Sopenharmony_cipublic: 1479e5c31af7Sopenharmony_ci LoadStoreTestInstance (Context& context, 1480e5c31af7Sopenharmony_ci const Texture& texture, 1481e5c31af7Sopenharmony_ci const VkFormat format, 1482e5c31af7Sopenharmony_ci const VkFormat imageFormat, 1483e5c31af7Sopenharmony_ci const bool declareImageFormatInShader, 1484e5c31af7Sopenharmony_ci const bool singleLayerBind, 1485e5c31af7Sopenharmony_ci const bool minalign, 1486e5c31af7Sopenharmony_ci const bool bufferLoadUniform); 1487e5c31af7Sopenharmony_ci 1488e5c31af7Sopenharmony_ciprotected: 1489e5c31af7Sopenharmony_ci virtual BufferWithMemory* getResultBuffer (void) const = 0; //!< Get the buffer that contains the result image 1490e5c31af7Sopenharmony_ci 1491e5c31af7Sopenharmony_ci tcu::TestStatus verifyResult (void); 1492e5c31af7Sopenharmony_ci 1493e5c31af7Sopenharmony_ci // Add empty implementations for functions that might be not needed 1494e5c31af7Sopenharmony_ci void commandBeforeCompute (const VkCommandBuffer) {} 1495e5c31af7Sopenharmony_ci void commandBetweenShaderInvocations (const VkCommandBuffer) {} 1496e5c31af7Sopenharmony_ci void commandAfterCompute (const VkCommandBuffer) {} 1497e5c31af7Sopenharmony_ci 1498e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> m_imageBuffer; //!< Source data and helper buffer 1499e5c31af7Sopenharmony_ci const VkDeviceSize m_imageSizeBytes; 1500e5c31af7Sopenharmony_ci const VkFormat m_imageFormat; //!< Image format (for storage, may be different than texture format) 1501e5c31af7Sopenharmony_ci tcu::TextureLevel m_referenceImage; //!< Used as input data and later to verify result image 1502e5c31af7Sopenharmony_ci 1503e5c31af7Sopenharmony_ci bool m_bufferLoadUniform; 1504e5c31af7Sopenharmony_ci VkDescriptorType m_bufferLoadDescriptorType; 1505e5c31af7Sopenharmony_ci VkBufferUsageFlagBits m_bufferLoadUsageBit; 1506e5c31af7Sopenharmony_ci}; 1507e5c31af7Sopenharmony_ci 1508e5c31af7Sopenharmony_ciLoadStoreTestInstance::LoadStoreTestInstance (Context& context, 1509e5c31af7Sopenharmony_ci const Texture& texture, 1510e5c31af7Sopenharmony_ci const VkFormat format, 1511e5c31af7Sopenharmony_ci const VkFormat imageFormat, 1512e5c31af7Sopenharmony_ci const bool declareImageFormatInShader, 1513e5c31af7Sopenharmony_ci const bool singleLayerBind, 1514e5c31af7Sopenharmony_ci const bool minalign, 1515e5c31af7Sopenharmony_ci const bool bufferLoadUniform) 1516e5c31af7Sopenharmony_ci : BaseTestInstance (context, texture, format, declareImageFormatInShader, singleLayerBind, minalign, bufferLoadUniform) 1517e5c31af7Sopenharmony_ci , m_imageSizeBytes (getImageSizeBytes(texture.size(), format)) 1518e5c31af7Sopenharmony_ci , m_imageFormat (imageFormat) 1519e5c31af7Sopenharmony_ci , m_referenceImage (generateReferenceImage(texture.size(), imageFormat, format)) 1520e5c31af7Sopenharmony_ci , m_bufferLoadUniform (bufferLoadUniform) 1521e5c31af7Sopenharmony_ci{ 1522e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 1523e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 1524e5c31af7Sopenharmony_ci Allocator& allocator = m_context.getDefaultAllocator(); 1525e5c31af7Sopenharmony_ci 1526e5c31af7Sopenharmony_ci m_bufferLoadDescriptorType = m_bufferLoadUniform ? VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER : VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 1527e5c31af7Sopenharmony_ci m_bufferLoadUsageBit = m_bufferLoadUniform ? VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; 1528e5c31af7Sopenharmony_ci 1529e5c31af7Sopenharmony_ci // A helper buffer with enough space to hold the whole image. 1530e5c31af7Sopenharmony_ci 1531e5c31af7Sopenharmony_ci m_imageBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory( 1532e5c31af7Sopenharmony_ci vk, device, allocator, 1533e5c31af7Sopenharmony_ci makeBufferCreateInfo(m_imageSizeBytes + m_srcViewOffset, m_bufferLoadUsageBit | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT), 1534e5c31af7Sopenharmony_ci MemoryRequirement::HostVisible)); 1535e5c31af7Sopenharmony_ci 1536e5c31af7Sopenharmony_ci // Copy reference data to buffer for subsequent upload to image. 1537e5c31af7Sopenharmony_ci 1538e5c31af7Sopenharmony_ci const Allocation& alloc = m_imageBuffer->getAllocation(); 1539e5c31af7Sopenharmony_ci deMemcpy((char *)alloc.getHostPtr() + m_srcViewOffset, m_referenceImage.getAccess().getDataPtr(), static_cast<size_t>(m_imageSizeBytes)); 1540e5c31af7Sopenharmony_ci flushAlloc(vk, device, alloc); 1541e5c31af7Sopenharmony_ci} 1542e5c31af7Sopenharmony_ci 1543e5c31af7Sopenharmony_citcu::TestStatus LoadStoreTestInstance::verifyResult (void) 1544e5c31af7Sopenharmony_ci{ 1545e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 1546e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 1547e5c31af7Sopenharmony_ci 1548e5c31af7Sopenharmony_ci // Apply the same transformation as done in the shader 1549e5c31af7Sopenharmony_ci const tcu::PixelBufferAccess reference = m_referenceImage.getAccess(); 1550e5c31af7Sopenharmony_ci flipHorizontally(reference); 1551e5c31af7Sopenharmony_ci 1552e5c31af7Sopenharmony_ci const Allocation& alloc = getResultBuffer()->getAllocation(); 1553e5c31af7Sopenharmony_ci invalidateAlloc(vk, device, alloc); 1554e5c31af7Sopenharmony_ci const tcu::ConstPixelBufferAccess result(mapVkFormat(m_imageFormat), m_texture.size(), (const char *)alloc.getHostPtr() + m_dstViewOffset); 1555e5c31af7Sopenharmony_ci 1556e5c31af7Sopenharmony_ci if (comparePixelBuffers(m_context.getTestContext().getLog(), m_texture, m_imageFormat, reference, result)) 1557e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("Passed"); 1558e5c31af7Sopenharmony_ci else 1559e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Image comparison failed"); 1560e5c31af7Sopenharmony_ci} 1561e5c31af7Sopenharmony_ci 1562e5c31af7Sopenharmony_ci//! Load/store test for images 1563e5c31af7Sopenharmony_ciclass ImageLoadStoreTestInstance : public LoadStoreTestInstance 1564e5c31af7Sopenharmony_ci{ 1565e5c31af7Sopenharmony_cipublic: 1566e5c31af7Sopenharmony_ci ImageLoadStoreTestInstance (Context& context, 1567e5c31af7Sopenharmony_ci const Texture& texture, 1568e5c31af7Sopenharmony_ci const VkFormat format, 1569e5c31af7Sopenharmony_ci const VkFormat imageFormat, 1570e5c31af7Sopenharmony_ci const VkImageTiling tiling, 1571e5c31af7Sopenharmony_ci const bool declareImageFormatInShader, 1572e5c31af7Sopenharmony_ci const bool singleLayerBind, 1573e5c31af7Sopenharmony_ci const bool minalign, 1574e5c31af7Sopenharmony_ci const bool bufferLoadUniform); 1575e5c31af7Sopenharmony_ci 1576e5c31af7Sopenharmony_ciprotected: 1577e5c31af7Sopenharmony_ci VkDescriptorSetLayout prepareDescriptors (void); 1578e5c31af7Sopenharmony_ci void commandBeforeCompute (const VkCommandBuffer cmdBuffer); 1579e5c31af7Sopenharmony_ci void commandBetweenShaderInvocations (const VkCommandBuffer cmdBuffer); 1580e5c31af7Sopenharmony_ci void commandAfterCompute (const VkCommandBuffer cmdBuffer); 1581e5c31af7Sopenharmony_ci 1582e5c31af7Sopenharmony_ci void commandBindDescriptorsForLayer (const VkCommandBuffer cmdBuffer, 1583e5c31af7Sopenharmony_ci const VkPipelineLayout pipelineLayout, 1584e5c31af7Sopenharmony_ci const int layerNdx); 1585e5c31af7Sopenharmony_ci 1586e5c31af7Sopenharmony_ci BufferWithMemory* getResultBuffer (void) const { return m_imageBuffer.get(); } 1587e5c31af7Sopenharmony_ci 1588e5c31af7Sopenharmony_ci de::MovePtr<Image> m_imageSrc; 1589e5c31af7Sopenharmony_ci de::MovePtr<Image> m_imageDst; 1590e5c31af7Sopenharmony_ci Move<VkDescriptorSetLayout> m_descriptorSetLayout; 1591e5c31af7Sopenharmony_ci Move<VkDescriptorPool> m_descriptorPool; 1592e5c31af7Sopenharmony_ci std::vector<SharedVkDescriptorSet> m_allDescriptorSets; 1593e5c31af7Sopenharmony_ci std::vector<SharedVkImageView> m_allSrcImageViews; 1594e5c31af7Sopenharmony_ci std::vector<SharedVkImageView> m_allDstImageViews; 1595e5c31af7Sopenharmony_ci}; 1596e5c31af7Sopenharmony_ci 1597e5c31af7Sopenharmony_ciImageLoadStoreTestInstance::ImageLoadStoreTestInstance (Context& context, 1598e5c31af7Sopenharmony_ci const Texture& texture, 1599e5c31af7Sopenharmony_ci const VkFormat format, 1600e5c31af7Sopenharmony_ci const VkFormat imageFormat, 1601e5c31af7Sopenharmony_ci const VkImageTiling tiling, 1602e5c31af7Sopenharmony_ci const bool declareImageFormatInShader, 1603e5c31af7Sopenharmony_ci const bool singleLayerBind, 1604e5c31af7Sopenharmony_ci const bool minalign, 1605e5c31af7Sopenharmony_ci const bool bufferLoadUniform) 1606e5c31af7Sopenharmony_ci : LoadStoreTestInstance (context, texture, format, imageFormat, declareImageFormatInShader, singleLayerBind, minalign, bufferLoadUniform) 1607e5c31af7Sopenharmony_ci , m_allDescriptorSets (texture.numLayers()) 1608e5c31af7Sopenharmony_ci , m_allSrcImageViews (texture.numLayers()) 1609e5c31af7Sopenharmony_ci , m_allDstImageViews (texture.numLayers()) 1610e5c31af7Sopenharmony_ci{ 1611e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 1612e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 1613e5c31af7Sopenharmony_ci Allocator& allocator = m_context.getDefaultAllocator(); 1614e5c31af7Sopenharmony_ci const VkImageCreateFlags imageFlags = (m_format == m_imageFormat ? 0u : (VkImageCreateFlags)VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT); 1615e5c31af7Sopenharmony_ci 1616e5c31af7Sopenharmony_ci m_imageSrc = de::MovePtr<Image>(new Image( 1617e5c31af7Sopenharmony_ci vk, device, allocator, 1618e5c31af7Sopenharmony_ci makeImageCreateInfo(m_texture, m_imageFormat, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, imageFlags, tiling), 1619e5c31af7Sopenharmony_ci MemoryRequirement::Any)); 1620e5c31af7Sopenharmony_ci 1621e5c31af7Sopenharmony_ci m_imageDst = de::MovePtr<Image>(new Image( 1622e5c31af7Sopenharmony_ci vk, device, allocator, 1623e5c31af7Sopenharmony_ci makeImageCreateInfo(m_texture, m_imageFormat, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, imageFlags, tiling), 1624e5c31af7Sopenharmony_ci MemoryRequirement::Any)); 1625e5c31af7Sopenharmony_ci} 1626e5c31af7Sopenharmony_ci 1627e5c31af7Sopenharmony_ciVkDescriptorSetLayout ImageLoadStoreTestInstance::prepareDescriptors (void) 1628e5c31af7Sopenharmony_ci{ 1629e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 1630e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 1631e5c31af7Sopenharmony_ci 1632e5c31af7Sopenharmony_ci const int numLayers = m_texture.numLayers(); 1633e5c31af7Sopenharmony_ci m_descriptorSetLayout = DescriptorSetLayoutBuilder() 1634e5c31af7Sopenharmony_ci .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 1635e5c31af7Sopenharmony_ci .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 1636e5c31af7Sopenharmony_ci .build(vk, device); 1637e5c31af7Sopenharmony_ci 1638e5c31af7Sopenharmony_ci m_descriptorPool = DescriptorPoolBuilder() 1639e5c31af7Sopenharmony_ci .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, numLayers) 1640e5c31af7Sopenharmony_ci .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, numLayers) 1641e5c31af7Sopenharmony_ci .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numLayers); 1642e5c31af7Sopenharmony_ci 1643e5c31af7Sopenharmony_ci if (m_singleLayerBind) 1644e5c31af7Sopenharmony_ci { 1645e5c31af7Sopenharmony_ci for (int layerNdx = 0; layerNdx < numLayers; ++layerNdx) 1646e5c31af7Sopenharmony_ci { 1647e5c31af7Sopenharmony_ci const VkImageViewType viewType = mapImageViewType(getImageTypeForSingleLayer(m_texture.type())); 1648e5c31af7Sopenharmony_ci const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, layerNdx, 1u); 1649e5c31af7Sopenharmony_ci 1650e5c31af7Sopenharmony_ci m_allDescriptorSets[layerNdx] = makeVkSharedPtr(makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout)); 1651e5c31af7Sopenharmony_ci m_allSrcImageViews[layerNdx] = makeVkSharedPtr(makeImageView(vk, device, m_imageSrc->get(), viewType, m_format, subresourceRange)); 1652e5c31af7Sopenharmony_ci m_allDstImageViews[layerNdx] = makeVkSharedPtr(makeImageView(vk, device, m_imageDst->get(), viewType, m_format, subresourceRange)); 1653e5c31af7Sopenharmony_ci } 1654e5c31af7Sopenharmony_ci } 1655e5c31af7Sopenharmony_ci else // bind all layers at once 1656e5c31af7Sopenharmony_ci { 1657e5c31af7Sopenharmony_ci const VkImageViewType viewType = mapImageViewType(m_texture.type()); 1658e5c31af7Sopenharmony_ci const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, numLayers); 1659e5c31af7Sopenharmony_ci 1660e5c31af7Sopenharmony_ci m_allDescriptorSets[0] = makeVkSharedPtr(makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout)); 1661e5c31af7Sopenharmony_ci m_allSrcImageViews[0] = makeVkSharedPtr(makeImageView(vk, device, m_imageSrc->get(), viewType, m_format, subresourceRange)); 1662e5c31af7Sopenharmony_ci m_allDstImageViews[0] = makeVkSharedPtr(makeImageView(vk, device, m_imageDst->get(), viewType, m_format, subresourceRange)); 1663e5c31af7Sopenharmony_ci } 1664e5c31af7Sopenharmony_ci 1665e5c31af7Sopenharmony_ci return *m_descriptorSetLayout; // not passing the ownership 1666e5c31af7Sopenharmony_ci} 1667e5c31af7Sopenharmony_ci 1668e5c31af7Sopenharmony_civoid ImageLoadStoreTestInstance::commandBindDescriptorsForLayer (const VkCommandBuffer cmdBuffer, const VkPipelineLayout pipelineLayout, const int layerNdx) 1669e5c31af7Sopenharmony_ci{ 1670e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 1671e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 1672e5c31af7Sopenharmony_ci 1673e5c31af7Sopenharmony_ci const VkDescriptorSet descriptorSet = **m_allDescriptorSets[layerNdx]; 1674e5c31af7Sopenharmony_ci const VkImageView srcImageView = **m_allSrcImageViews[layerNdx]; 1675e5c31af7Sopenharmony_ci const VkImageView dstImageView = **m_allDstImageViews[layerNdx]; 1676e5c31af7Sopenharmony_ci 1677e5c31af7Sopenharmony_ci const VkDescriptorImageInfo descriptorSrcImageInfo = makeDescriptorImageInfo(DE_NULL, srcImageView, VK_IMAGE_LAYOUT_GENERAL); 1678e5c31af7Sopenharmony_ci const VkDescriptorImageInfo descriptorDstImageInfo = makeDescriptorImageInfo(DE_NULL, dstImageView, VK_IMAGE_LAYOUT_GENERAL); 1679e5c31af7Sopenharmony_ci 1680e5c31af7Sopenharmony_ci DescriptorSetUpdateBuilder() 1681e5c31af7Sopenharmony_ci .writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorSrcImageInfo) 1682e5c31af7Sopenharmony_ci .writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorDstImageInfo) 1683e5c31af7Sopenharmony_ci .update(vk, device); 1684e5c31af7Sopenharmony_ci vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL); 1685e5c31af7Sopenharmony_ci} 1686e5c31af7Sopenharmony_ci 1687e5c31af7Sopenharmony_civoid ImageLoadStoreTestInstance::commandBeforeCompute (const VkCommandBuffer cmdBuffer) 1688e5c31af7Sopenharmony_ci{ 1689e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 1690e5c31af7Sopenharmony_ci 1691e5c31af7Sopenharmony_ci const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_texture.numLayers()); 1692e5c31af7Sopenharmony_ci { 1693e5c31af7Sopenharmony_ci const VkImageMemoryBarrier preCopyImageBarriers[] = 1694e5c31af7Sopenharmony_ci { 1695e5c31af7Sopenharmony_ci makeImageMemoryBarrier( 1696e5c31af7Sopenharmony_ci 0u, VK_ACCESS_TRANSFER_WRITE_BIT, 1697e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1698e5c31af7Sopenharmony_ci m_imageSrc->get(), fullImageSubresourceRange), 1699e5c31af7Sopenharmony_ci makeImageMemoryBarrier( 1700e5c31af7Sopenharmony_ci 0u, VK_ACCESS_SHADER_WRITE_BIT, 1701e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, 1702e5c31af7Sopenharmony_ci m_imageDst->get(), fullImageSubresourceRange) 1703e5c31af7Sopenharmony_ci }; 1704e5c31af7Sopenharmony_ci 1705e5c31af7Sopenharmony_ci const VkBufferMemoryBarrier barrierFlushHostWriteBeforeCopy = makeBufferMemoryBarrier( 1706e5c31af7Sopenharmony_ci VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, 1707e5c31af7Sopenharmony_ci m_imageBuffer->get(), 0ull, m_imageSizeBytes + m_srcViewOffset); 1708e5c31af7Sopenharmony_ci 1709e5c31af7Sopenharmony_ci vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, 1710e5c31af7Sopenharmony_ci (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &barrierFlushHostWriteBeforeCopy, DE_LENGTH_OF_ARRAY(preCopyImageBarriers), preCopyImageBarriers); 1711e5c31af7Sopenharmony_ci } 1712e5c31af7Sopenharmony_ci { 1713e5c31af7Sopenharmony_ci const VkImageMemoryBarrier barrierAfterCopy = makeImageMemoryBarrier( 1714e5c31af7Sopenharmony_ci VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, 1715e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, 1716e5c31af7Sopenharmony_ci m_imageSrc->get(), fullImageSubresourceRange); 1717e5c31af7Sopenharmony_ci 1718e5c31af7Sopenharmony_ci const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_texture); 1719e5c31af7Sopenharmony_ci 1720e5c31af7Sopenharmony_ci vk.cmdCopyBufferToImage(cmdBuffer, m_imageBuffer->get(), m_imageSrc->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region); 1721e5c31af7Sopenharmony_ci vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &barrierAfterCopy); 1722e5c31af7Sopenharmony_ci } 1723e5c31af7Sopenharmony_ci} 1724e5c31af7Sopenharmony_ci 1725e5c31af7Sopenharmony_civoid ImageLoadStoreTestInstance::commandBetweenShaderInvocations (const VkCommandBuffer cmdBuffer) 1726e5c31af7Sopenharmony_ci{ 1727e5c31af7Sopenharmony_ci commandImageWriteBarrierBetweenShaderInvocations(m_context, cmdBuffer, m_imageDst->get(), m_texture); 1728e5c31af7Sopenharmony_ci} 1729e5c31af7Sopenharmony_ci 1730e5c31af7Sopenharmony_civoid ImageLoadStoreTestInstance::commandAfterCompute (const VkCommandBuffer cmdBuffer) 1731e5c31af7Sopenharmony_ci{ 1732e5c31af7Sopenharmony_ci commandCopyImageToBuffer(m_context, cmdBuffer, m_imageDst->get(), m_imageBuffer->get(), m_imageSizeBytes, m_texture); 1733e5c31af7Sopenharmony_ci} 1734e5c31af7Sopenharmony_ci 1735e5c31af7Sopenharmony_ci//! Load/store Lod AMD test for images 1736e5c31af7Sopenharmony_ciclass ImageLoadStoreLodAMDTestInstance : public BaseTestInstance 1737e5c31af7Sopenharmony_ci{ 1738e5c31af7Sopenharmony_cipublic: 1739e5c31af7Sopenharmony_ci ImageLoadStoreLodAMDTestInstance (Context& context, 1740e5c31af7Sopenharmony_ci const Texture& texture, 1741e5c31af7Sopenharmony_ci const VkFormat format, 1742e5c31af7Sopenharmony_ci const VkFormat imageFormat, 1743e5c31af7Sopenharmony_ci const bool declareImageFormatInShader, 1744e5c31af7Sopenharmony_ci const bool singleLayerBind, 1745e5c31af7Sopenharmony_ci const bool minalign, 1746e5c31af7Sopenharmony_ci const bool bufferLoadUniform); 1747e5c31af7Sopenharmony_ci 1748e5c31af7Sopenharmony_ciprotected: 1749e5c31af7Sopenharmony_ci VkDescriptorSetLayout prepareDescriptors (void); 1750e5c31af7Sopenharmony_ci void commandBeforeCompute (const VkCommandBuffer cmdBuffer); 1751e5c31af7Sopenharmony_ci void commandBetweenShaderInvocations (const VkCommandBuffer cmdBuffer); 1752e5c31af7Sopenharmony_ci void commandAfterCompute (const VkCommandBuffer cmdBuffer); 1753e5c31af7Sopenharmony_ci 1754e5c31af7Sopenharmony_ci void commandBindDescriptorsForLayer (const VkCommandBuffer cmdBuffer, 1755e5c31af7Sopenharmony_ci const VkPipelineLayout pipelineLayout, 1756e5c31af7Sopenharmony_ci const int layerNdx); 1757e5c31af7Sopenharmony_ci 1758e5c31af7Sopenharmony_ci BufferWithMemory* getResultBuffer (void) const { return m_imageBuffer.get(); } 1759e5c31af7Sopenharmony_ci tcu::TestStatus verifyResult (void); 1760e5c31af7Sopenharmony_ci 1761e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> m_imageBuffer; //!< Source data and helper buffer 1762e5c31af7Sopenharmony_ci const VkDeviceSize m_imageSizeBytes; 1763e5c31af7Sopenharmony_ci const VkFormat m_imageFormat; //!< Image format (for storage, may be different than texture format) 1764e5c31af7Sopenharmony_ci std::vector<tcu::TextureLevel> m_referenceImages; //!< Used as input data and later to verify result image 1765e5c31af7Sopenharmony_ci 1766e5c31af7Sopenharmony_ci bool m_bufferLoadUniform; 1767e5c31af7Sopenharmony_ci VkDescriptorType m_bufferLoadDescriptorType; 1768e5c31af7Sopenharmony_ci VkBufferUsageFlagBits m_bufferLoadUsageBit; 1769e5c31af7Sopenharmony_ci 1770e5c31af7Sopenharmony_ci de::MovePtr<Image> m_imageSrc; 1771e5c31af7Sopenharmony_ci de::MovePtr<Image> m_imageDst; 1772e5c31af7Sopenharmony_ci Move<VkDescriptorSetLayout> m_descriptorSetLayout; 1773e5c31af7Sopenharmony_ci Move<VkDescriptorPool> m_descriptorPool; 1774e5c31af7Sopenharmony_ci std::vector<SharedVkDescriptorSet> m_allDescriptorSets; 1775e5c31af7Sopenharmony_ci std::vector<SharedVkImageView> m_allSrcImageViews; 1776e5c31af7Sopenharmony_ci std::vector<SharedVkImageView> m_allDstImageViews; 1777e5c31af7Sopenharmony_ci 1778e5c31af7Sopenharmony_ci}; 1779e5c31af7Sopenharmony_ci 1780e5c31af7Sopenharmony_ciImageLoadStoreLodAMDTestInstance::ImageLoadStoreLodAMDTestInstance (Context& context, 1781e5c31af7Sopenharmony_ci const Texture& texture, 1782e5c31af7Sopenharmony_ci const VkFormat format, 1783e5c31af7Sopenharmony_ci const VkFormat imageFormat, 1784e5c31af7Sopenharmony_ci const bool declareImageFormatInShader, 1785e5c31af7Sopenharmony_ci const bool singleLayerBind, 1786e5c31af7Sopenharmony_ci const bool minalign, 1787e5c31af7Sopenharmony_ci const bool bufferLoadUniform) 1788e5c31af7Sopenharmony_ci : BaseTestInstance (context, texture, format, declareImageFormatInShader, singleLayerBind, minalign, bufferLoadUniform) 1789e5c31af7Sopenharmony_ci , m_imageSizeBytes (getMipmapImageTotalSizeBytes(texture, format)) 1790e5c31af7Sopenharmony_ci , m_imageFormat (imageFormat) 1791e5c31af7Sopenharmony_ci , m_bufferLoadUniform (bufferLoadUniform) 1792e5c31af7Sopenharmony_ci , m_allDescriptorSets (texture.numLayers()) 1793e5c31af7Sopenharmony_ci , m_allSrcImageViews (texture.numLayers()) 1794e5c31af7Sopenharmony_ci , m_allDstImageViews (texture.numLayers()) 1795e5c31af7Sopenharmony_ci{ 1796e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 1797e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 1798e5c31af7Sopenharmony_ci Allocator& allocator = m_context.getDefaultAllocator(); 1799e5c31af7Sopenharmony_ci const VkImageCreateFlags imageFlags = (m_format == m_imageFormat ? 0u : (VkImageCreateFlags)VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT); 1800e5c31af7Sopenharmony_ci 1801e5c31af7Sopenharmony_ci const VkSampleCountFlagBits samples = static_cast<VkSampleCountFlagBits>(m_texture.numSamples()); // integer and bit mask are aligned, so we can cast like this 1802e5c31af7Sopenharmony_ci 1803e5c31af7Sopenharmony_ci for (deInt32 levelNdx = 0; levelNdx < m_texture.numMipmapLevels(); levelNdx++) 1804e5c31af7Sopenharmony_ci { 1805e5c31af7Sopenharmony_ci tcu::TextureLevel referenceImage = generateReferenceImage(texture.size(levelNdx), imageFormat, format); 1806e5c31af7Sopenharmony_ci m_referenceImages.push_back(referenceImage); 1807e5c31af7Sopenharmony_ci } 1808e5c31af7Sopenharmony_ci 1809e5c31af7Sopenharmony_ci m_bufferLoadDescriptorType = m_bufferLoadUniform ? VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER : VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 1810e5c31af7Sopenharmony_ci m_bufferLoadUsageBit = m_bufferLoadUniform ? VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; 1811e5c31af7Sopenharmony_ci 1812e5c31af7Sopenharmony_ci // A helper buffer with enough space to hold the whole image. 1813e5c31af7Sopenharmony_ci m_imageBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory( 1814e5c31af7Sopenharmony_ci vk, device, allocator, 1815e5c31af7Sopenharmony_ci makeBufferCreateInfo(m_imageSizeBytes + m_srcViewOffset, m_bufferLoadUsageBit | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT), 1816e5c31af7Sopenharmony_ci MemoryRequirement::HostVisible)); 1817e5c31af7Sopenharmony_ci 1818e5c31af7Sopenharmony_ci // Copy reference data to buffer for subsequent upload to image. 1819e5c31af7Sopenharmony_ci { 1820e5c31af7Sopenharmony_ci const Allocation& alloc = m_imageBuffer->getAllocation(); 1821e5c31af7Sopenharmony_ci VkDeviceSize bufferOffset = 0u; 1822e5c31af7Sopenharmony_ci for (deInt32 levelNdx = 0; levelNdx < m_texture.numMipmapLevels(); levelNdx++) 1823e5c31af7Sopenharmony_ci { 1824e5c31af7Sopenharmony_ci deMemcpy((char *)alloc.getHostPtr() + m_srcViewOffset + bufferOffset, m_referenceImages[levelNdx].getAccess().getDataPtr(), static_cast<size_t>(getMipmapLevelImageSizeBytes(m_texture, m_imageFormat, levelNdx))); 1825e5c31af7Sopenharmony_ci bufferOffset += getMipmapLevelImageSizeBytes(m_texture, m_imageFormat, levelNdx); 1826e5c31af7Sopenharmony_ci } 1827e5c31af7Sopenharmony_ci flushAlloc(vk, device, alloc); 1828e5c31af7Sopenharmony_ci } 1829e5c31af7Sopenharmony_ci 1830e5c31af7Sopenharmony_ci { 1831e5c31af7Sopenharmony_ci const VkImageCreateInfo imageParamsSrc = 1832e5c31af7Sopenharmony_ci { 1833e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1834e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 1835e5c31af7Sopenharmony_ci (isCube(m_texture) ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0u) | imageFlags, // VkImageCreateFlags flags; 1836e5c31af7Sopenharmony_ci mapImageType(m_texture.type()), // VkImageType imageType; 1837e5c31af7Sopenharmony_ci m_imageFormat, // VkFormat format; 1838e5c31af7Sopenharmony_ci makeExtent3D(m_texture.layerSize()), // VkExtent3D extent; 1839e5c31af7Sopenharmony_ci (deUint32)m_texture.numMipmapLevels(), // deUint32 mipLevels; 1840e5c31af7Sopenharmony_ci (deUint32)m_texture.numLayers(), // deUint32 arrayLayers; 1841e5c31af7Sopenharmony_ci samples, // VkSampleCountFlagBits samples; 1842e5c31af7Sopenharmony_ci VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1843e5c31af7Sopenharmony_ci VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage; 1844e5c31af7Sopenharmony_ci VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1845e5c31af7Sopenharmony_ci 0u, // deUint32 queueFamilyIndexCount; 1846e5c31af7Sopenharmony_ci DE_NULL, // const deUint32* pQueueFamilyIndices; 1847e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1848e5c31af7Sopenharmony_ci }; 1849e5c31af7Sopenharmony_ci 1850e5c31af7Sopenharmony_ci m_imageSrc = de::MovePtr<Image>(new Image( 1851e5c31af7Sopenharmony_ci vk, device, allocator, 1852e5c31af7Sopenharmony_ci imageParamsSrc, 1853e5c31af7Sopenharmony_ci MemoryRequirement::Any)); 1854e5c31af7Sopenharmony_ci } 1855e5c31af7Sopenharmony_ci 1856e5c31af7Sopenharmony_ci { 1857e5c31af7Sopenharmony_ci const VkImageCreateInfo imageParamsDst = 1858e5c31af7Sopenharmony_ci { 1859e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1860e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 1861e5c31af7Sopenharmony_ci (isCube(m_texture) ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0u) | imageFlags, // VkImageCreateFlags flags; 1862e5c31af7Sopenharmony_ci mapImageType(m_texture.type()), // VkImageType imageType; 1863e5c31af7Sopenharmony_ci m_imageFormat, // VkFormat format; 1864e5c31af7Sopenharmony_ci makeExtent3D(m_texture.layerSize()), // VkExtent3D extent; 1865e5c31af7Sopenharmony_ci (deUint32)m_texture.numMipmapLevels(), // deUint32 mipLevels; 1866e5c31af7Sopenharmony_ci (deUint32)m_texture.numLayers(), // deUint32 arrayLayers; 1867e5c31af7Sopenharmony_ci samples, // VkSampleCountFlagBits samples; 1868e5c31af7Sopenharmony_ci VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1869e5c31af7Sopenharmony_ci VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; 1870e5c31af7Sopenharmony_ci VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1871e5c31af7Sopenharmony_ci 0u, // deUint32 queueFamilyIndexCount; 1872e5c31af7Sopenharmony_ci DE_NULL, // const deUint32* pQueueFamilyIndices; 1873e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1874e5c31af7Sopenharmony_ci }; 1875e5c31af7Sopenharmony_ci 1876e5c31af7Sopenharmony_ci m_imageDst = de::MovePtr<Image>(new Image( 1877e5c31af7Sopenharmony_ci vk, device, allocator, 1878e5c31af7Sopenharmony_ci imageParamsDst, 1879e5c31af7Sopenharmony_ci MemoryRequirement::Any)); 1880e5c31af7Sopenharmony_ci } 1881e5c31af7Sopenharmony_ci} 1882e5c31af7Sopenharmony_ci 1883e5c31af7Sopenharmony_citcu::TestStatus ImageLoadStoreLodAMDTestInstance::verifyResult (void) 1884e5c31af7Sopenharmony_ci{ 1885e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 1886e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 1887e5c31af7Sopenharmony_ci 1888e5c31af7Sopenharmony_ci const Allocation& alloc = getResultBuffer()->getAllocation(); 1889e5c31af7Sopenharmony_ci invalidateAlloc(vk, device, alloc); 1890e5c31af7Sopenharmony_ci 1891e5c31af7Sopenharmony_ci VkDeviceSize bufferOffset = 0; 1892e5c31af7Sopenharmony_ci for (deInt32 levelNdx = 0; levelNdx < m_texture.numMipmapLevels(); levelNdx++) 1893e5c31af7Sopenharmony_ci { 1894e5c31af7Sopenharmony_ci // Apply the same transformation as done in the shader 1895e5c31af7Sopenharmony_ci const tcu::PixelBufferAccess reference = m_referenceImages[levelNdx].getAccess(); 1896e5c31af7Sopenharmony_ci flipHorizontally(reference); 1897e5c31af7Sopenharmony_ci 1898e5c31af7Sopenharmony_ci const tcu::ConstPixelBufferAccess result(mapVkFormat(m_imageFormat), m_texture.size(levelNdx), (const char *)alloc.getHostPtr() + m_dstViewOffset + bufferOffset); 1899e5c31af7Sopenharmony_ci 1900e5c31af7Sopenharmony_ci if (!comparePixelBuffers(m_context.getTestContext().getLog(), m_texture, m_imageFormat, reference, result, levelNdx)) 1901e5c31af7Sopenharmony_ci { 1902e5c31af7Sopenharmony_ci std::ostringstream errorMessage; 1903e5c31af7Sopenharmony_ci errorMessage << "Image Level " << levelNdx << " comparison failed"; 1904e5c31af7Sopenharmony_ci return tcu::TestStatus::fail(errorMessage.str()); 1905e5c31af7Sopenharmony_ci } 1906e5c31af7Sopenharmony_ci bufferOffset += getMipmapLevelImageSizeBytes(m_texture, m_imageFormat, levelNdx); 1907e5c31af7Sopenharmony_ci } 1908e5c31af7Sopenharmony_ci 1909e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("Passed"); 1910e5c31af7Sopenharmony_ci} 1911e5c31af7Sopenharmony_ci 1912e5c31af7Sopenharmony_ciVkDescriptorSetLayout ImageLoadStoreLodAMDTestInstance::prepareDescriptors (void) 1913e5c31af7Sopenharmony_ci{ 1914e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 1915e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 1916e5c31af7Sopenharmony_ci 1917e5c31af7Sopenharmony_ci const int numLayers = m_texture.numLayers(); 1918e5c31af7Sopenharmony_ci m_descriptorSetLayout = DescriptorSetLayoutBuilder() 1919e5c31af7Sopenharmony_ci .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 1920e5c31af7Sopenharmony_ci .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 1921e5c31af7Sopenharmony_ci .build(vk, device); 1922e5c31af7Sopenharmony_ci 1923e5c31af7Sopenharmony_ci m_descriptorPool = DescriptorPoolBuilder() 1924e5c31af7Sopenharmony_ci .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, numLayers) 1925e5c31af7Sopenharmony_ci .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, numLayers) 1926e5c31af7Sopenharmony_ci .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numLayers); 1927e5c31af7Sopenharmony_ci 1928e5c31af7Sopenharmony_ci if (m_singleLayerBind) 1929e5c31af7Sopenharmony_ci { 1930e5c31af7Sopenharmony_ci for (int layerNdx = 0; layerNdx < numLayers; ++layerNdx) 1931e5c31af7Sopenharmony_ci { 1932e5c31af7Sopenharmony_ci const VkImageViewType viewType = mapImageViewType(getImageTypeForSingleLayer(m_texture.type())); 1933e5c31af7Sopenharmony_ci const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, m_texture.numMipmapLevels(), layerNdx, 1u); 1934e5c31af7Sopenharmony_ci 1935e5c31af7Sopenharmony_ci m_allDescriptorSets[layerNdx] = makeVkSharedPtr(makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout)); 1936e5c31af7Sopenharmony_ci m_allSrcImageViews[layerNdx] = makeVkSharedPtr(makeImageView(vk, device, m_imageSrc->get(), viewType, m_format, subresourceRange)); 1937e5c31af7Sopenharmony_ci m_allDstImageViews[layerNdx] = makeVkSharedPtr(makeImageView(vk, device, m_imageDst->get(), viewType, m_format, subresourceRange)); 1938e5c31af7Sopenharmony_ci } 1939e5c31af7Sopenharmony_ci } 1940e5c31af7Sopenharmony_ci else // bind all layers at once 1941e5c31af7Sopenharmony_ci { 1942e5c31af7Sopenharmony_ci const VkImageViewType viewType = mapImageViewType(m_texture.type()); 1943e5c31af7Sopenharmony_ci const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, m_texture.numMipmapLevels(), 0u, numLayers); 1944e5c31af7Sopenharmony_ci 1945e5c31af7Sopenharmony_ci m_allDescriptorSets[0] = makeVkSharedPtr(makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout)); 1946e5c31af7Sopenharmony_ci m_allSrcImageViews[0] = makeVkSharedPtr(makeImageView(vk, device, m_imageSrc->get(), viewType, m_format, subresourceRange)); 1947e5c31af7Sopenharmony_ci m_allDstImageViews[0] = makeVkSharedPtr(makeImageView(vk, device, m_imageDst->get(), viewType, m_format, subresourceRange)); 1948e5c31af7Sopenharmony_ci } 1949e5c31af7Sopenharmony_ci 1950e5c31af7Sopenharmony_ci return *m_descriptorSetLayout; // not passing the ownership 1951e5c31af7Sopenharmony_ci} 1952e5c31af7Sopenharmony_ci 1953e5c31af7Sopenharmony_civoid ImageLoadStoreLodAMDTestInstance::commandBindDescriptorsForLayer (const VkCommandBuffer cmdBuffer, const VkPipelineLayout pipelineLayout, const int layerNdx) 1954e5c31af7Sopenharmony_ci{ 1955e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 1956e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 1957e5c31af7Sopenharmony_ci 1958e5c31af7Sopenharmony_ci const VkDescriptorSet descriptorSet = **m_allDescriptorSets[layerNdx]; 1959e5c31af7Sopenharmony_ci const VkImageView srcImageView = **m_allSrcImageViews[layerNdx]; 1960e5c31af7Sopenharmony_ci const VkImageView dstImageView = **m_allDstImageViews[layerNdx]; 1961e5c31af7Sopenharmony_ci 1962e5c31af7Sopenharmony_ci const VkDescriptorImageInfo descriptorSrcImageInfo = makeDescriptorImageInfo(DE_NULL, srcImageView, VK_IMAGE_LAYOUT_GENERAL); 1963e5c31af7Sopenharmony_ci const VkDescriptorImageInfo descriptorDstImageInfo = makeDescriptorImageInfo(DE_NULL, dstImageView, VK_IMAGE_LAYOUT_GENERAL); 1964e5c31af7Sopenharmony_ci 1965e5c31af7Sopenharmony_ci DescriptorSetUpdateBuilder() 1966e5c31af7Sopenharmony_ci .writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorSrcImageInfo) 1967e5c31af7Sopenharmony_ci .writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorDstImageInfo) 1968e5c31af7Sopenharmony_ci .update(vk, device); 1969e5c31af7Sopenharmony_ci vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL); 1970e5c31af7Sopenharmony_ci} 1971e5c31af7Sopenharmony_ci 1972e5c31af7Sopenharmony_civoid ImageLoadStoreLodAMDTestInstance::commandBeforeCompute (const VkCommandBuffer cmdBuffer) 1973e5c31af7Sopenharmony_ci{ 1974e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 1975e5c31af7Sopenharmony_ci const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, m_texture.numMipmapLevels(), 0u, m_texture.numLayers()); 1976e5c31af7Sopenharmony_ci { 1977e5c31af7Sopenharmony_ci const VkImageMemoryBarrier preCopyImageBarriers[] = 1978e5c31af7Sopenharmony_ci { 1979e5c31af7Sopenharmony_ci makeImageMemoryBarrier( 1980e5c31af7Sopenharmony_ci 0u, VK_ACCESS_TRANSFER_WRITE_BIT, 1981e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1982e5c31af7Sopenharmony_ci m_imageSrc->get(), fullImageSubresourceRange), 1983e5c31af7Sopenharmony_ci makeImageMemoryBarrier( 1984e5c31af7Sopenharmony_ci 0u, VK_ACCESS_SHADER_WRITE_BIT, 1985e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, 1986e5c31af7Sopenharmony_ci m_imageDst->get(), fullImageSubresourceRange) 1987e5c31af7Sopenharmony_ci }; 1988e5c31af7Sopenharmony_ci 1989e5c31af7Sopenharmony_ci const VkBufferMemoryBarrier barrierFlushHostWriteBeforeCopy = makeBufferMemoryBarrier( 1990e5c31af7Sopenharmony_ci VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, 1991e5c31af7Sopenharmony_ci m_imageBuffer->get(), 0ull, m_imageSizeBytes + m_srcViewOffset); 1992e5c31af7Sopenharmony_ci 1993e5c31af7Sopenharmony_ci vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, 1994e5c31af7Sopenharmony_ci (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &barrierFlushHostWriteBeforeCopy, DE_LENGTH_OF_ARRAY(preCopyImageBarriers), preCopyImageBarriers); 1995e5c31af7Sopenharmony_ci } 1996e5c31af7Sopenharmony_ci { 1997e5c31af7Sopenharmony_ci const VkImageMemoryBarrier barrierAfterCopy = makeImageMemoryBarrier( 1998e5c31af7Sopenharmony_ci VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, 1999e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, 2000e5c31af7Sopenharmony_ci m_imageSrc->get(), fullImageSubresourceRange); 2001e5c31af7Sopenharmony_ci 2002e5c31af7Sopenharmony_ci std::vector<VkBufferImageCopy> copyRegions; 2003e5c31af7Sopenharmony_ci VkDeviceSize bufferOffset = 0u; 2004e5c31af7Sopenharmony_ci for (deInt32 levelNdx = 0; levelNdx < m_texture.numMipmapLevels(); levelNdx++) 2005e5c31af7Sopenharmony_ci { 2006e5c31af7Sopenharmony_ci const VkBufferImageCopy copyParams = 2007e5c31af7Sopenharmony_ci { 2008e5c31af7Sopenharmony_ci bufferOffset, // VkDeviceSize bufferOffset; 2009e5c31af7Sopenharmony_ci 0u, // deUint32 bufferRowLength; 2010e5c31af7Sopenharmony_ci 0u, // deUint32 bufferImageHeight; 2011e5c31af7Sopenharmony_ci makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, levelNdx, 0u, m_texture.numLayers()), // VkImageSubresourceLayers imageSubresource; 2012e5c31af7Sopenharmony_ci makeOffset3D(0, 0, 0), // VkOffset3D imageOffset; 2013e5c31af7Sopenharmony_ci makeExtent3D(m_texture.layerSize(levelNdx)), // VkExtent3D imageExtent; 2014e5c31af7Sopenharmony_ci }; 2015e5c31af7Sopenharmony_ci copyRegions.push_back(copyParams); 2016e5c31af7Sopenharmony_ci bufferOffset += getMipmapLevelImageSizeBytes(m_texture, m_imageFormat, levelNdx); 2017e5c31af7Sopenharmony_ci } 2018e5c31af7Sopenharmony_ci 2019e5c31af7Sopenharmony_ci vk.cmdCopyBufferToImage(cmdBuffer, m_imageBuffer->get(), m_imageSrc->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32) copyRegions.size(), copyRegions.data()); 2020e5c31af7Sopenharmony_ci vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &barrierAfterCopy); 2021e5c31af7Sopenharmony_ci } 2022e5c31af7Sopenharmony_ci} 2023e5c31af7Sopenharmony_ci 2024e5c31af7Sopenharmony_civoid ImageLoadStoreLodAMDTestInstance::commandBetweenShaderInvocations (const VkCommandBuffer cmdBuffer) 2025e5c31af7Sopenharmony_ci{ 2026e5c31af7Sopenharmony_ci commandImageWriteBarrierBetweenShaderInvocations(m_context, cmdBuffer, m_imageDst->get(), m_texture); 2027e5c31af7Sopenharmony_ci} 2028e5c31af7Sopenharmony_ci 2029e5c31af7Sopenharmony_civoid ImageLoadStoreLodAMDTestInstance::commandAfterCompute (const VkCommandBuffer cmdBuffer) 2030e5c31af7Sopenharmony_ci{ 2031e5c31af7Sopenharmony_ci commandCopyMipmapImageToBuffer(m_context, cmdBuffer, m_imageDst->get(), m_imageFormat, m_imageBuffer->get(), m_imageSizeBytes, m_texture); 2032e5c31af7Sopenharmony_ci} 2033e5c31af7Sopenharmony_ci 2034e5c31af7Sopenharmony_ci//! Load/store test for buffers 2035e5c31af7Sopenharmony_ciclass BufferLoadStoreTestInstance : public LoadStoreTestInstance 2036e5c31af7Sopenharmony_ci{ 2037e5c31af7Sopenharmony_cipublic: 2038e5c31af7Sopenharmony_ci BufferLoadStoreTestInstance (Context& context, 2039e5c31af7Sopenharmony_ci const Texture& texture, 2040e5c31af7Sopenharmony_ci const VkFormat format, 2041e5c31af7Sopenharmony_ci const VkFormat imageFormat, 2042e5c31af7Sopenharmony_ci const bool declareImageFormatInShader, 2043e5c31af7Sopenharmony_ci const bool minalign, 2044e5c31af7Sopenharmony_ci const bool bufferLoadUniform); 2045e5c31af7Sopenharmony_ci 2046e5c31af7Sopenharmony_ciprotected: 2047e5c31af7Sopenharmony_ci VkDescriptorSetLayout prepareDescriptors (void); 2048e5c31af7Sopenharmony_ci void commandAfterCompute (const VkCommandBuffer cmdBuffer); 2049e5c31af7Sopenharmony_ci 2050e5c31af7Sopenharmony_ci void commandBindDescriptorsForLayer (const VkCommandBuffer cmdBuffer, 2051e5c31af7Sopenharmony_ci const VkPipelineLayout pipelineLayout, 2052e5c31af7Sopenharmony_ci const int layerNdx); 2053e5c31af7Sopenharmony_ci 2054e5c31af7Sopenharmony_ci BufferWithMemory* getResultBuffer (void) const { return m_imageBufferDst.get(); } 2055e5c31af7Sopenharmony_ci 2056e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> m_imageBufferDst; 2057e5c31af7Sopenharmony_ci Move<VkDescriptorSetLayout> m_descriptorSetLayout; 2058e5c31af7Sopenharmony_ci Move<VkDescriptorPool> m_descriptorPool; 2059e5c31af7Sopenharmony_ci Move<VkDescriptorSet> m_descriptorSet; 2060e5c31af7Sopenharmony_ci Move<VkBufferView> m_bufferViewSrc; 2061e5c31af7Sopenharmony_ci Move<VkBufferView> m_bufferViewDst; 2062e5c31af7Sopenharmony_ci}; 2063e5c31af7Sopenharmony_ci 2064e5c31af7Sopenharmony_ciBufferLoadStoreTestInstance::BufferLoadStoreTestInstance (Context& context, 2065e5c31af7Sopenharmony_ci const Texture& texture, 2066e5c31af7Sopenharmony_ci const VkFormat format, 2067e5c31af7Sopenharmony_ci const VkFormat imageFormat, 2068e5c31af7Sopenharmony_ci const bool declareImageFormatInShader, 2069e5c31af7Sopenharmony_ci const bool minalign, 2070e5c31af7Sopenharmony_ci const bool bufferLoadUniform) 2071e5c31af7Sopenharmony_ci : LoadStoreTestInstance(context, texture, format, imageFormat, declareImageFormatInShader, false, minalign, bufferLoadUniform) 2072e5c31af7Sopenharmony_ci{ 2073e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 2074e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 2075e5c31af7Sopenharmony_ci Allocator& allocator = m_context.getDefaultAllocator(); 2076e5c31af7Sopenharmony_ci 2077e5c31af7Sopenharmony_ci // Create a destination buffer. 2078e5c31af7Sopenharmony_ci 2079e5c31af7Sopenharmony_ci m_imageBufferDst = de::MovePtr<BufferWithMemory>(new BufferWithMemory( 2080e5c31af7Sopenharmony_ci vk, device, allocator, 2081e5c31af7Sopenharmony_ci makeBufferCreateInfo(m_imageSizeBytes + m_dstViewOffset, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT), 2082e5c31af7Sopenharmony_ci MemoryRequirement::HostVisible)); 2083e5c31af7Sopenharmony_ci} 2084e5c31af7Sopenharmony_ci 2085e5c31af7Sopenharmony_ciVkDescriptorSetLayout BufferLoadStoreTestInstance::prepareDescriptors (void) 2086e5c31af7Sopenharmony_ci{ 2087e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 2088e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 2089e5c31af7Sopenharmony_ci 2090e5c31af7Sopenharmony_ci m_descriptorSetLayout = DescriptorSetLayoutBuilder() 2091e5c31af7Sopenharmony_ci .addSingleBinding(m_bufferLoadDescriptorType, VK_SHADER_STAGE_COMPUTE_BIT) 2092e5c31af7Sopenharmony_ci .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) 2093e5c31af7Sopenharmony_ci .build(vk, device); 2094e5c31af7Sopenharmony_ci 2095e5c31af7Sopenharmony_ci m_descriptorPool = DescriptorPoolBuilder() 2096e5c31af7Sopenharmony_ci .addType(m_bufferLoadDescriptorType) 2097e5c31af7Sopenharmony_ci .addType(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) 2098e5c31af7Sopenharmony_ci .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 2099e5c31af7Sopenharmony_ci 2100e5c31af7Sopenharmony_ci VkFormat dstFormat = formatHasThreeComponents(m_format) ? getSingleComponentFormat(m_format) : m_format; 2101e5c31af7Sopenharmony_ci 2102e5c31af7Sopenharmony_ci m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout); 2103e5c31af7Sopenharmony_ci m_bufferViewSrc = makeBufferView(vk, device, m_imageBuffer->get(), m_format, m_srcViewOffset, m_imageSizeBytes); 2104e5c31af7Sopenharmony_ci m_bufferViewDst = makeBufferView(vk, device, m_imageBufferDst->get(), dstFormat, m_dstViewOffset, m_imageSizeBytes); 2105e5c31af7Sopenharmony_ci 2106e5c31af7Sopenharmony_ci return *m_descriptorSetLayout; // not passing the ownership 2107e5c31af7Sopenharmony_ci} 2108e5c31af7Sopenharmony_ci 2109e5c31af7Sopenharmony_civoid BufferLoadStoreTestInstance::commandBindDescriptorsForLayer (const VkCommandBuffer cmdBuffer, const VkPipelineLayout pipelineLayout, const int layerNdx) 2110e5c31af7Sopenharmony_ci{ 2111e5c31af7Sopenharmony_ci DE_ASSERT(layerNdx == 0); 2112e5c31af7Sopenharmony_ci DE_UNREF(layerNdx); 2113e5c31af7Sopenharmony_ci 2114e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 2115e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 2116e5c31af7Sopenharmony_ci 2117e5c31af7Sopenharmony_ci DescriptorSetUpdateBuilder() 2118e5c31af7Sopenharmony_ci .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), m_bufferLoadDescriptorType, &m_bufferViewSrc.get()) 2119e5c31af7Sopenharmony_ci .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, &m_bufferViewDst.get()) 2120e5c31af7Sopenharmony_ci .update(vk, device); 2121e5c31af7Sopenharmony_ci vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL); 2122e5c31af7Sopenharmony_ci} 2123e5c31af7Sopenharmony_ci 2124e5c31af7Sopenharmony_civoid BufferLoadStoreTestInstance::commandAfterCompute (const VkCommandBuffer cmdBuffer) 2125e5c31af7Sopenharmony_ci{ 2126e5c31af7Sopenharmony_ci commandBufferWriteBarrierBeforeHostRead(m_context, cmdBuffer, m_imageBufferDst->get(), m_imageSizeBytes + m_dstViewOffset); 2127e5c31af7Sopenharmony_ci} 2128e5c31af7Sopenharmony_ci 2129e5c31af7Sopenharmony_ciTestInstance* StoreTest::createInstance (Context& context) const 2130e5c31af7Sopenharmony_ci{ 2131e5c31af7Sopenharmony_ci if (m_texture.type() == IMAGE_TYPE_BUFFER) 2132e5c31af7Sopenharmony_ci return new BufferStoreTestInstance(context, m_texture, m_format, m_declareImageFormatInShader, m_minalign, m_storeConstantValue); 2133e5c31af7Sopenharmony_ci else 2134e5c31af7Sopenharmony_ci return new ImageStoreTestInstance(context, m_texture, m_format, m_tiling, m_declareImageFormatInShader, m_singleLayerBind, m_minalign, m_storeConstantValue); 2135e5c31af7Sopenharmony_ci} 2136e5c31af7Sopenharmony_ci 2137e5c31af7Sopenharmony_ciTestInstance* LoadStoreTest::createInstance (Context& context) const 2138e5c31af7Sopenharmony_ci{ 2139e5c31af7Sopenharmony_ci if (m_imageLoadStoreLodAMD) 2140e5c31af7Sopenharmony_ci return new ImageLoadStoreLodAMDTestInstance(context, m_texture, m_format, m_imageFormat, m_declareFormatInShaderReads, m_singleLayerBind, m_minalign, m_bufferLoadUniform); 2141e5c31af7Sopenharmony_ci 2142e5c31af7Sopenharmony_ci if (m_texture.type() == IMAGE_TYPE_BUFFER) 2143e5c31af7Sopenharmony_ci return new BufferLoadStoreTestInstance(context, m_texture, m_format, m_imageFormat, m_declareFormatInShaderReads, m_minalign, m_bufferLoadUniform); 2144e5c31af7Sopenharmony_ci else 2145e5c31af7Sopenharmony_ci return new ImageLoadStoreTestInstance(context, m_texture, m_format, m_imageFormat, m_tiling, m_declareFormatInShaderReads, m_singleLayerBind, m_minalign, m_bufferLoadUniform); 2146e5c31af7Sopenharmony_ci} 2147e5c31af7Sopenharmony_ci 2148e5c31af7Sopenharmony_ciclass ImageExtendOperandTestInstance : public BaseTestInstance 2149e5c31af7Sopenharmony_ci{ 2150e5c31af7Sopenharmony_cipublic: 2151e5c31af7Sopenharmony_ci ImageExtendOperandTestInstance (Context& context, 2152e5c31af7Sopenharmony_ci const Texture& texture, 2153e5c31af7Sopenharmony_ci const VkFormat readFormat, 2154e5c31af7Sopenharmony_ci const VkFormat writeFormat, 2155e5c31af7Sopenharmony_ci bool relaxedPrecision); 2156e5c31af7Sopenharmony_ci 2157e5c31af7Sopenharmony_ci virtual ~ImageExtendOperandTestInstance (void) {} 2158e5c31af7Sopenharmony_ci 2159e5c31af7Sopenharmony_ciprotected: 2160e5c31af7Sopenharmony_ci 2161e5c31af7Sopenharmony_ci VkDescriptorSetLayout prepareDescriptors (void); 2162e5c31af7Sopenharmony_ci void commandBeforeCompute (const VkCommandBuffer cmdBuffer); 2163e5c31af7Sopenharmony_ci void commandBetweenShaderInvocations (const VkCommandBuffer cmdBuffer); 2164e5c31af7Sopenharmony_ci void commandAfterCompute (const VkCommandBuffer cmdBuffer); 2165e5c31af7Sopenharmony_ci 2166e5c31af7Sopenharmony_ci void commandBindDescriptorsForLayer (const VkCommandBuffer cmdBuffer, 2167e5c31af7Sopenharmony_ci const VkPipelineLayout pipelineLayout, 2168e5c31af7Sopenharmony_ci const int layerNdx); 2169e5c31af7Sopenharmony_ci 2170e5c31af7Sopenharmony_ci tcu::TestStatus verifyResult (void); 2171e5c31af7Sopenharmony_ci 2172e5c31af7Sopenharmony_ciprotected: 2173e5c31af7Sopenharmony_ci 2174e5c31af7Sopenharmony_ci bool m_isSigned; 2175e5c31af7Sopenharmony_ci tcu::TextureLevel m_inputImageData; 2176e5c31af7Sopenharmony_ci 2177e5c31af7Sopenharmony_ci de::MovePtr<Image> m_imageSrc; // source image 2178e5c31af7Sopenharmony_ci SharedVkImageView m_imageSrcView; 2179e5c31af7Sopenharmony_ci VkDeviceSize m_imageSrcSize; 2180e5c31af7Sopenharmony_ci 2181e5c31af7Sopenharmony_ci de::MovePtr<Image> m_imageDst; // dest image 2182e5c31af7Sopenharmony_ci SharedVkImageView m_imageDstView; 2183e5c31af7Sopenharmony_ci VkFormat m_imageDstFormat; 2184e5c31af7Sopenharmony_ci VkDeviceSize m_imageDstSize; 2185e5c31af7Sopenharmony_ci 2186e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> m_buffer; // result buffer 2187e5c31af7Sopenharmony_ci 2188e5c31af7Sopenharmony_ci Move<VkDescriptorSetLayout> m_descriptorSetLayout; 2189e5c31af7Sopenharmony_ci Move<VkDescriptorPool> m_descriptorPool; 2190e5c31af7Sopenharmony_ci SharedVkDescriptorSet m_descriptorSet; 2191e5c31af7Sopenharmony_ci 2192e5c31af7Sopenharmony_ci bool m_relaxedPrecision; 2193e5c31af7Sopenharmony_ci}; 2194e5c31af7Sopenharmony_ci 2195e5c31af7Sopenharmony_ciImageExtendOperandTestInstance::ImageExtendOperandTestInstance (Context& context, 2196e5c31af7Sopenharmony_ci const Texture& texture, 2197e5c31af7Sopenharmony_ci const VkFormat readFormat, 2198e5c31af7Sopenharmony_ci const VkFormat writeFormat, 2199e5c31af7Sopenharmony_ci bool relaxedPrecision) 2200e5c31af7Sopenharmony_ci : BaseTestInstance (context, texture, readFormat, true, true, false, false) 2201e5c31af7Sopenharmony_ci , m_imageDstFormat (writeFormat) 2202e5c31af7Sopenharmony_ci , m_relaxedPrecision (relaxedPrecision) 2203e5c31af7Sopenharmony_ci{ 2204e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 2205e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 2206e5c31af7Sopenharmony_ci Allocator& allocator = m_context.getDefaultAllocator(); 2207e5c31af7Sopenharmony_ci const deInt32 width = texture.size().x(); 2208e5c31af7Sopenharmony_ci const deInt32 height = texture.size().y(); 2209e5c31af7Sopenharmony_ci const tcu::TextureFormat textureFormat = mapVkFormat(m_format); 2210e5c31af7Sopenharmony_ci 2211e5c31af7Sopenharmony_ci // Generate reference image 2212e5c31af7Sopenharmony_ci m_isSigned = (getTextureChannelClass(textureFormat.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER); 2213e5c31af7Sopenharmony_ci m_inputImageData.setStorage(textureFormat, width, height, 1); 2214e5c31af7Sopenharmony_ci 2215e5c31af7Sopenharmony_ci const tcu::PixelBufferAccess access = m_inputImageData.getAccess(); 2216e5c31af7Sopenharmony_ci const int valueStart = (m_isSigned ? (-width / 2) : 0); 2217e5c31af7Sopenharmony_ci 2218e5c31af7Sopenharmony_ci for (int x = 0; x < width; ++x) 2219e5c31af7Sopenharmony_ci for (int y = 0; y < height; ++y) 2220e5c31af7Sopenharmony_ci { 2221e5c31af7Sopenharmony_ci const tcu::IVec4 color(valueStart + x, valueStart + y, valueStart, valueStart); 2222e5c31af7Sopenharmony_ci access.setPixel(color, x, y); 2223e5c31af7Sopenharmony_ci } 2224e5c31af7Sopenharmony_ci 2225e5c31af7Sopenharmony_ci // Create source image 2226e5c31af7Sopenharmony_ci m_imageSrc = de::MovePtr<Image>(new Image( 2227e5c31af7Sopenharmony_ci vk, device, allocator, 2228e5c31af7Sopenharmony_ci makeImageCreateInfo(m_texture, m_format, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0u), 2229e5c31af7Sopenharmony_ci MemoryRequirement::Any)); 2230e5c31af7Sopenharmony_ci 2231e5c31af7Sopenharmony_ci // Create destination image 2232e5c31af7Sopenharmony_ci m_imageDst = de::MovePtr<Image>(new Image( 2233e5c31af7Sopenharmony_ci vk, device, allocator, 2234e5c31af7Sopenharmony_ci makeImageCreateInfo(m_texture, m_imageDstFormat, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0u), 2235e5c31af7Sopenharmony_ci MemoryRequirement::Any)); 2236e5c31af7Sopenharmony_ci 2237e5c31af7Sopenharmony_ci // Compute image and buffer sizes 2238e5c31af7Sopenharmony_ci m_imageSrcSize = width * height * tcu::getPixelSize(textureFormat); 2239e5c31af7Sopenharmony_ci m_imageDstSize = width * height * tcu::getPixelSize(mapVkFormat(m_imageDstFormat)); 2240e5c31af7Sopenharmony_ci VkDeviceSize bufferSizeBytes = de::max(m_imageSrcSize, m_imageDstSize); 2241e5c31af7Sopenharmony_ci 2242e5c31af7Sopenharmony_ci // Create helper buffer able to store input data and image write result 2243e5c31af7Sopenharmony_ci m_buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory( 2244e5c31af7Sopenharmony_ci vk, device, allocator, 2245e5c31af7Sopenharmony_ci makeBufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT), 2246e5c31af7Sopenharmony_ci MemoryRequirement::HostVisible)); 2247e5c31af7Sopenharmony_ci 2248e5c31af7Sopenharmony_ci const Allocation& alloc = m_buffer->getAllocation(); 2249e5c31af7Sopenharmony_ci deMemcpy(alloc.getHostPtr(), m_inputImageData.getAccess().getDataPtr(), static_cast<size_t>(m_imageSrcSize)); 2250e5c31af7Sopenharmony_ci flushAlloc(vk, device, alloc); 2251e5c31af7Sopenharmony_ci} 2252e5c31af7Sopenharmony_ci 2253e5c31af7Sopenharmony_ciVkDescriptorSetLayout ImageExtendOperandTestInstance::prepareDescriptors (void) 2254e5c31af7Sopenharmony_ci{ 2255e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 2256e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 2257e5c31af7Sopenharmony_ci 2258e5c31af7Sopenharmony_ci m_descriptorSetLayout = DescriptorSetLayoutBuilder() 2259e5c31af7Sopenharmony_ci .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 2260e5c31af7Sopenharmony_ci .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT) 2261e5c31af7Sopenharmony_ci .build(vk, device); 2262e5c31af7Sopenharmony_ci 2263e5c31af7Sopenharmony_ci m_descriptorPool = DescriptorPoolBuilder() 2264e5c31af7Sopenharmony_ci .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1) 2265e5c31af7Sopenharmony_ci .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1) 2266e5c31af7Sopenharmony_ci .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1); 2267e5c31af7Sopenharmony_ci 2268e5c31af7Sopenharmony_ci const VkImageViewType viewType = mapImageViewType(m_texture.type()); 2269e5c31af7Sopenharmony_ci const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); 2270e5c31af7Sopenharmony_ci 2271e5c31af7Sopenharmony_ci m_descriptorSet = makeVkSharedPtr(makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout)); 2272e5c31af7Sopenharmony_ci m_imageSrcView = makeVkSharedPtr(makeImageView(vk, device, m_imageSrc->get(), viewType, m_format, subresourceRange)); 2273e5c31af7Sopenharmony_ci m_imageDstView = makeVkSharedPtr(makeImageView(vk, device, m_imageDst->get(), viewType, m_imageDstFormat, subresourceRange)); 2274e5c31af7Sopenharmony_ci 2275e5c31af7Sopenharmony_ci return *m_descriptorSetLayout; // not passing the ownership 2276e5c31af7Sopenharmony_ci} 2277e5c31af7Sopenharmony_ci 2278e5c31af7Sopenharmony_civoid ImageExtendOperandTestInstance::commandBindDescriptorsForLayer (const VkCommandBuffer cmdBuffer, const VkPipelineLayout pipelineLayout, const int layerNdx) 2279e5c31af7Sopenharmony_ci{ 2280e5c31af7Sopenharmony_ci DE_UNREF(layerNdx); 2281e5c31af7Sopenharmony_ci 2282e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 2283e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 2284e5c31af7Sopenharmony_ci const VkDescriptorSet descriptorSet = **m_descriptorSet; 2285e5c31af7Sopenharmony_ci 2286e5c31af7Sopenharmony_ci const VkDescriptorImageInfo descriptorSrcImageInfo = makeDescriptorImageInfo(DE_NULL, **m_imageSrcView, VK_IMAGE_LAYOUT_GENERAL); 2287e5c31af7Sopenharmony_ci const VkDescriptorImageInfo descriptorDstImageInfo = makeDescriptorImageInfo(DE_NULL, **m_imageDstView, VK_IMAGE_LAYOUT_GENERAL); 2288e5c31af7Sopenharmony_ci 2289e5c31af7Sopenharmony_ci typedef DescriptorSetUpdateBuilder::Location DSUBL; 2290e5c31af7Sopenharmony_ci DescriptorSetUpdateBuilder() 2291e5c31af7Sopenharmony_ci .writeSingle(descriptorSet, DSUBL::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorSrcImageInfo) 2292e5c31af7Sopenharmony_ci .writeSingle(descriptorSet, DSUBL::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorDstImageInfo) 2293e5c31af7Sopenharmony_ci .update(vk, device); 2294e5c31af7Sopenharmony_ci vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL); 2295e5c31af7Sopenharmony_ci} 2296e5c31af7Sopenharmony_ci 2297e5c31af7Sopenharmony_civoid ImageExtendOperandTestInstance::commandBeforeCompute (const VkCommandBuffer cmdBuffer) 2298e5c31af7Sopenharmony_ci{ 2299e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 2300e5c31af7Sopenharmony_ci 2301e5c31af7Sopenharmony_ci const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_texture.numLayers()); 2302e5c31af7Sopenharmony_ci { 2303e5c31af7Sopenharmony_ci const VkImageMemoryBarrier preCopyImageBarriers[] = 2304e5c31af7Sopenharmony_ci { 2305e5c31af7Sopenharmony_ci makeImageMemoryBarrier( 2306e5c31af7Sopenharmony_ci 0u, VK_ACCESS_TRANSFER_WRITE_BIT, 2307e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 2308e5c31af7Sopenharmony_ci m_imageSrc->get(), fullImageSubresourceRange), 2309e5c31af7Sopenharmony_ci makeImageMemoryBarrier( 2310e5c31af7Sopenharmony_ci 0u, VK_ACCESS_SHADER_WRITE_BIT, 2311e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, 2312e5c31af7Sopenharmony_ci m_imageDst->get(), fullImageSubresourceRange) 2313e5c31af7Sopenharmony_ci }; 2314e5c31af7Sopenharmony_ci 2315e5c31af7Sopenharmony_ci const VkBufferMemoryBarrier barrierFlushHostWriteBeforeCopy = makeBufferMemoryBarrier( 2316e5c31af7Sopenharmony_ci VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, 2317e5c31af7Sopenharmony_ci m_buffer->get(), 0ull, m_imageSrcSize); 2318e5c31af7Sopenharmony_ci 2319e5c31af7Sopenharmony_ci vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, 2320e5c31af7Sopenharmony_ci (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &barrierFlushHostWriteBeforeCopy, DE_LENGTH_OF_ARRAY(preCopyImageBarriers), preCopyImageBarriers); 2321e5c31af7Sopenharmony_ci } 2322e5c31af7Sopenharmony_ci { 2323e5c31af7Sopenharmony_ci const VkImageMemoryBarrier barrierAfterCopy = makeImageMemoryBarrier( 2324e5c31af7Sopenharmony_ci VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, 2325e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, 2326e5c31af7Sopenharmony_ci m_imageSrc->get(), fullImageSubresourceRange); 2327e5c31af7Sopenharmony_ci 2328e5c31af7Sopenharmony_ci const VkBufferImageCopy copyRegion = makeBufferImageCopy(m_texture); 2329e5c31af7Sopenharmony_ci 2330e5c31af7Sopenharmony_ci vk.cmdCopyBufferToImage(cmdBuffer, m_buffer->get(), m_imageSrc->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region); 2331e5c31af7Sopenharmony_ci vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &barrierAfterCopy); 2332e5c31af7Sopenharmony_ci } 2333e5c31af7Sopenharmony_ci} 2334e5c31af7Sopenharmony_ci 2335e5c31af7Sopenharmony_civoid ImageExtendOperandTestInstance::commandBetweenShaderInvocations (const VkCommandBuffer cmdBuffer) 2336e5c31af7Sopenharmony_ci{ 2337e5c31af7Sopenharmony_ci commandImageWriteBarrierBetweenShaderInvocations(m_context, cmdBuffer, m_imageDst->get(), m_texture); 2338e5c31af7Sopenharmony_ci} 2339e5c31af7Sopenharmony_ci 2340e5c31af7Sopenharmony_civoid ImageExtendOperandTestInstance::commandAfterCompute (const VkCommandBuffer cmdBuffer) 2341e5c31af7Sopenharmony_ci{ 2342e5c31af7Sopenharmony_ci commandCopyImageToBuffer(m_context, cmdBuffer, m_imageDst->get(), m_buffer->get(), m_imageDstSize, m_texture); 2343e5c31af7Sopenharmony_ci} 2344e5c31af7Sopenharmony_ci 2345e5c31af7Sopenharmony_ci// Clears the high bits of every pixel in the pixel buffer, leaving only the lowest 16 bits of each component. 2346e5c31af7Sopenharmony_civoid clearHighBits (const tcu::PixelBufferAccess& pixels, int width, int height) 2347e5c31af7Sopenharmony_ci{ 2348e5c31af7Sopenharmony_ci for (int y = 0; y < height; ++y) 2349e5c31af7Sopenharmony_ci for (int x = 0; x < width; ++x) 2350e5c31af7Sopenharmony_ci { 2351e5c31af7Sopenharmony_ci auto color = pixels.getPixelUint(x, y); 2352e5c31af7Sopenharmony_ci for (int c = 0; c < decltype(color)::SIZE; ++c) 2353e5c31af7Sopenharmony_ci color[c] &= 0xFFFFull; 2354e5c31af7Sopenharmony_ci pixels.setPixel(color, x, y); 2355e5c31af7Sopenharmony_ci } 2356e5c31af7Sopenharmony_ci} 2357e5c31af7Sopenharmony_ci 2358e5c31af7Sopenharmony_citcu::TestStatus ImageExtendOperandTestInstance::verifyResult (void) 2359e5c31af7Sopenharmony_ci{ 2360e5c31af7Sopenharmony_ci const DeviceInterface& vk = m_context.getDeviceInterface(); 2361e5c31af7Sopenharmony_ci const VkDevice device = m_context.getDevice(); 2362e5c31af7Sopenharmony_ci const tcu::IVec3 imageSize = m_texture.size(); 2363e5c31af7Sopenharmony_ci const tcu::PixelBufferAccess inputAccess = m_inputImageData.getAccess(); 2364e5c31af7Sopenharmony_ci const deInt32 width = inputAccess.getWidth(); 2365e5c31af7Sopenharmony_ci const deInt32 height = inputAccess.getHeight(); 2366e5c31af7Sopenharmony_ci tcu::TextureLevel refImage (mapVkFormat(m_imageDstFormat), width, height); 2367e5c31af7Sopenharmony_ci tcu::PixelBufferAccess refAccess = refImage.getAccess(); 2368e5c31af7Sopenharmony_ci 2369e5c31af7Sopenharmony_ci for (int x = 0; x < width; ++x) 2370e5c31af7Sopenharmony_ci for (int y = 0; y < height; ++y) 2371e5c31af7Sopenharmony_ci { 2372e5c31af7Sopenharmony_ci tcu::IVec4 color = inputAccess.getPixelInt(x, y); 2373e5c31af7Sopenharmony_ci refAccess.setPixel(color, x, y); 2374e5c31af7Sopenharmony_ci } 2375e5c31af7Sopenharmony_ci 2376e5c31af7Sopenharmony_ci const Allocation& alloc = m_buffer->getAllocation(); 2377e5c31af7Sopenharmony_ci invalidateAlloc(vk, device, alloc); 2378e5c31af7Sopenharmony_ci const tcu::PixelBufferAccess result(mapVkFormat(m_imageDstFormat), imageSize, alloc.getHostPtr()); 2379e5c31af7Sopenharmony_ci 2380e5c31af7Sopenharmony_ci if (m_relaxedPrecision) 2381e5c31af7Sopenharmony_ci { 2382e5c31af7Sopenharmony_ci // Preserve the lowest 16 bits of the reference and result pixels only. 2383e5c31af7Sopenharmony_ci clearHighBits(refAccess, width, height); 2384e5c31af7Sopenharmony_ci clearHighBits(result, width, height); 2385e5c31af7Sopenharmony_ci } 2386e5c31af7Sopenharmony_ci 2387e5c31af7Sopenharmony_ci if (tcu::intThresholdCompare (m_context.getTestContext().getLog(), "Comparison", "Comparison", refAccess, result, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT, true/*use64Bits*/)) 2388e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("Passed"); 2389e5c31af7Sopenharmony_ci else 2390e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Image comparison failed"); 2391e5c31af7Sopenharmony_ci} 2392e5c31af7Sopenharmony_ci 2393e5c31af7Sopenharmony_cienum class ExtendTestType 2394e5c31af7Sopenharmony_ci{ 2395e5c31af7Sopenharmony_ci READ = 0, 2396e5c31af7Sopenharmony_ci WRITE, 2397e5c31af7Sopenharmony_ci WRITE_NONTEMPORAL, 2398e5c31af7Sopenharmony_ci}; 2399e5c31af7Sopenharmony_ci 2400e5c31af7Sopenharmony_cienum class ExtendOperand 2401e5c31af7Sopenharmony_ci{ 2402e5c31af7Sopenharmony_ci SIGN_EXTEND = 0, 2403e5c31af7Sopenharmony_ci ZERO_EXTEND = 1 2404e5c31af7Sopenharmony_ci}; 2405e5c31af7Sopenharmony_ci 2406e5c31af7Sopenharmony_ciclass ImageExtendOperandTest : public TestCase 2407e5c31af7Sopenharmony_ci{ 2408e5c31af7Sopenharmony_cipublic: 2409e5c31af7Sopenharmony_ci ImageExtendOperandTest (tcu::TestContext& testCtx, 2410e5c31af7Sopenharmony_ci const std::string& name, 2411e5c31af7Sopenharmony_ci const Texture texture, 2412e5c31af7Sopenharmony_ci const VkFormat readFormat, 2413e5c31af7Sopenharmony_ci const VkFormat writeFormat, 2414e5c31af7Sopenharmony_ci const bool signedInt, 2415e5c31af7Sopenharmony_ci const bool relaxedPrecision, 2416e5c31af7Sopenharmony_ci ExtendTestType extendTestType); 2417e5c31af7Sopenharmony_ci 2418e5c31af7Sopenharmony_ci void checkSupport (Context& context) const; 2419e5c31af7Sopenharmony_ci void initPrograms (SourceCollections& programCollection) const; 2420e5c31af7Sopenharmony_ci TestInstance* createInstance (Context& context) const; 2421e5c31af7Sopenharmony_ci 2422e5c31af7Sopenharmony_ciprivate: 2423e5c31af7Sopenharmony_ci bool isWriteTest () const { return (m_extendTestType == ExtendTestType::WRITE) || 2424e5c31af7Sopenharmony_ci (m_extendTestType == ExtendTestType::WRITE_NONTEMPORAL); } 2425e5c31af7Sopenharmony_ci 2426e5c31af7Sopenharmony_ci const Texture m_texture; 2427e5c31af7Sopenharmony_ci VkFormat m_readFormat; 2428e5c31af7Sopenharmony_ci VkFormat m_writeFormat; 2429e5c31af7Sopenharmony_ci bool m_operandForce; // Use an operand that doesn't match SampledType? 2430e5c31af7Sopenharmony_ci bool m_relaxedPrecision; 2431e5c31af7Sopenharmony_ci ExtendTestType m_extendTestType; 2432e5c31af7Sopenharmony_ci}; 2433e5c31af7Sopenharmony_ci 2434e5c31af7Sopenharmony_ciImageExtendOperandTest::ImageExtendOperandTest (tcu::TestContext& testCtx, 2435e5c31af7Sopenharmony_ci const std::string& name, 2436e5c31af7Sopenharmony_ci const Texture texture, 2437e5c31af7Sopenharmony_ci const VkFormat readFormat, 2438e5c31af7Sopenharmony_ci const VkFormat writeFormat, 2439e5c31af7Sopenharmony_ci const bool operandForce, 2440e5c31af7Sopenharmony_ci const bool relaxedPrecision, 2441e5c31af7Sopenharmony_ci ExtendTestType extendTestType) 2442e5c31af7Sopenharmony_ci : TestCase (testCtx, name) 2443e5c31af7Sopenharmony_ci , m_texture (texture) 2444e5c31af7Sopenharmony_ci , m_readFormat (readFormat) 2445e5c31af7Sopenharmony_ci , m_writeFormat (writeFormat) 2446e5c31af7Sopenharmony_ci , m_operandForce (operandForce) 2447e5c31af7Sopenharmony_ci , m_relaxedPrecision (relaxedPrecision) 2448e5c31af7Sopenharmony_ci , m_extendTestType (extendTestType) 2449e5c31af7Sopenharmony_ci{ 2450e5c31af7Sopenharmony_ci} 2451e5c31af7Sopenharmony_ci 2452e5c31af7Sopenharmony_civoid checkFormatProperties (const Context& context, VkFormat format) 2453e5c31af7Sopenharmony_ci{ 2454e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 2455e5c31af7Sopenharmony_ci const VkFormatProperties3 formatProperties (context.getFormatProperties(format)); 2456e5c31af7Sopenharmony_ci 2457e5c31af7Sopenharmony_ci if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) 2458e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for storage images"); 2459e5c31af7Sopenharmony_ci#else 2460e5c31af7Sopenharmony_ci const VkFormatProperties formatProperties(getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format)); 2461e5c31af7Sopenharmony_ci 2462e5c31af7Sopenharmony_ci if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) 2463e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Format not supported for storage images"); 2464e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 2465e5c31af7Sopenharmony_ci} 2466e5c31af7Sopenharmony_ci 2467e5c31af7Sopenharmony_civoid check64BitSupportIfNeeded (Context& context, VkFormat readFormat, VkFormat writeFormat) 2468e5c31af7Sopenharmony_ci{ 2469e5c31af7Sopenharmony_ci if (is64BitIntegerFormat(readFormat) || is64BitIntegerFormat(writeFormat)) 2470e5c31af7Sopenharmony_ci { 2471e5c31af7Sopenharmony_ci const auto& features = context.getDeviceFeatures(); 2472e5c31af7Sopenharmony_ci if (!features.shaderInt64) 2473e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "64-bit integers not supported in shaders"); 2474e5c31af7Sopenharmony_ci } 2475e5c31af7Sopenharmony_ci} 2476e5c31af7Sopenharmony_ci 2477e5c31af7Sopenharmony_civoid ImageExtendOperandTest::checkSupport (Context& context) const 2478e5c31af7Sopenharmony_ci{ 2479e5c31af7Sopenharmony_ci if (!context.requireDeviceFunctionality("VK_KHR_spirv_1_4")) 2480e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "VK_KHR_spirv_1_4 not supported"); 2481e5c31af7Sopenharmony_ci 2482e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 2483e5c31af7Sopenharmony_ci DE_ASSERT(m_readFormat != VK_FORMAT_A8_UNORM_KHR && m_writeFormat != VK_FORMAT_A8_UNORM_KHR); 2484e5c31af7Sopenharmony_ci DE_ASSERT(m_readFormat != VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR && m_writeFormat != VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR); 2485e5c31af7Sopenharmony_ci 2486e5c31af7Sopenharmony_ci if ((m_extendTestType == ExtendTestType::WRITE_NONTEMPORAL) && 2487e5c31af7Sopenharmony_ci (context.getUsedApiVersion() < VK_API_VERSION_1_3)) 2488e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Vulkan 1.3 or higher is required for this test to run"); 2489e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 2490e5c31af7Sopenharmony_ci 2491e5c31af7Sopenharmony_ci check64BitSupportIfNeeded(context, m_readFormat, m_writeFormat); 2492e5c31af7Sopenharmony_ci 2493e5c31af7Sopenharmony_ci checkFormatProperties(context, m_readFormat); 2494e5c31af7Sopenharmony_ci checkFormatProperties(context, m_writeFormat); 2495e5c31af7Sopenharmony_ci} 2496e5c31af7Sopenharmony_ci 2497e5c31af7Sopenharmony_civoid ImageExtendOperandTest::initPrograms (SourceCollections& programCollection) const 2498e5c31af7Sopenharmony_ci{ 2499e5c31af7Sopenharmony_ci tcu::StringTemplate shaderTemplate( 2500e5c31af7Sopenharmony_ci "OpCapability Shader\n" 2501e5c31af7Sopenharmony_ci "OpCapability StorageImageExtendedFormats\n" 2502e5c31af7Sopenharmony_ci 2503e5c31af7Sopenharmony_ci "${capability}" 2504e5c31af7Sopenharmony_ci "${extension}" 2505e5c31af7Sopenharmony_ci 2506e5c31af7Sopenharmony_ci "%std450 = OpExtInstImport \"GLSL.std.450\"\n" 2507e5c31af7Sopenharmony_ci "OpMemoryModel Logical GLSL450\n" 2508e5c31af7Sopenharmony_ci "OpEntryPoint GLCompute %main \"main\" %id %src_image_ptr %dst_image_ptr\n" 2509e5c31af7Sopenharmony_ci "OpExecutionMode %main LocalSize 1 1 1\n" 2510e5c31af7Sopenharmony_ci 2511e5c31af7Sopenharmony_ci // decorations 2512e5c31af7Sopenharmony_ci "OpDecorate %id BuiltIn GlobalInvocationId\n" 2513e5c31af7Sopenharmony_ci 2514e5c31af7Sopenharmony_ci "OpDecorate %src_image_ptr DescriptorSet 0\n" 2515e5c31af7Sopenharmony_ci "OpDecorate %src_image_ptr Binding 0\n" 2516e5c31af7Sopenharmony_ci "OpDecorate %src_image_ptr NonWritable\n" 2517e5c31af7Sopenharmony_ci 2518e5c31af7Sopenharmony_ci "${relaxed_precision}" 2519e5c31af7Sopenharmony_ci 2520e5c31af7Sopenharmony_ci "OpDecorate %dst_image_ptr DescriptorSet 0\n" 2521e5c31af7Sopenharmony_ci "OpDecorate %dst_image_ptr Binding 1\n" 2522e5c31af7Sopenharmony_ci "OpDecorate %dst_image_ptr NonReadable\n" 2523e5c31af7Sopenharmony_ci 2524e5c31af7Sopenharmony_ci // types 2525e5c31af7Sopenharmony_ci "%type_void = OpTypeVoid\n" 2526e5c31af7Sopenharmony_ci "%type_i32 = OpTypeInt 32 1\n" 2527e5c31af7Sopenharmony_ci "%type_u32 = OpTypeInt 32 0\n" 2528e5c31af7Sopenharmony_ci "%type_vec2_i32 = OpTypeVector %type_i32 2\n" 2529e5c31af7Sopenharmony_ci "%type_vec2_u32 = OpTypeVector %type_u32 2\n" 2530e5c31af7Sopenharmony_ci "%type_vec3_i32 = OpTypeVector %type_i32 3\n" 2531e5c31af7Sopenharmony_ci "%type_vec3_u32 = OpTypeVector %type_u32 3\n" 2532e5c31af7Sopenharmony_ci "%type_vec4_i32 = OpTypeVector %type_i32 4\n" 2533e5c31af7Sopenharmony_ci "%type_vec4_u32 = OpTypeVector %type_u32 4\n" 2534e5c31af7Sopenharmony_ci "${extra_types}" 2535e5c31af7Sopenharmony_ci 2536e5c31af7Sopenharmony_ci "%type_fun_void = OpTypeFunction %type_void\n" 2537e5c31af7Sopenharmony_ci 2538e5c31af7Sopenharmony_ci "${image_types}" 2539e5c31af7Sopenharmony_ci 2540e5c31af7Sopenharmony_ci "%type_ptr_in_vec3_u32 = OpTypePointer Input %type_vec3_u32\n" 2541e5c31af7Sopenharmony_ci "%type_ptr_in_u32 = OpTypePointer Input %type_u32\n" 2542e5c31af7Sopenharmony_ci 2543e5c31af7Sopenharmony_ci "${image_uniforms}" 2544e5c31af7Sopenharmony_ci 2545e5c31af7Sopenharmony_ci // variables 2546e5c31af7Sopenharmony_ci "%id = OpVariable %type_ptr_in_vec3_u32 Input\n" 2547e5c31af7Sopenharmony_ci 2548e5c31af7Sopenharmony_ci "${image_variables}" 2549e5c31af7Sopenharmony_ci 2550e5c31af7Sopenharmony_ci // main function 2551e5c31af7Sopenharmony_ci "%main = OpFunction %type_void None %type_fun_void\n" 2552e5c31af7Sopenharmony_ci "%label = OpLabel\n" 2553e5c31af7Sopenharmony_ci 2554e5c31af7Sopenharmony_ci "${image_load}" 2555e5c31af7Sopenharmony_ci 2556e5c31af7Sopenharmony_ci "%idvec = OpLoad %type_vec3_u32 %id\n" 2557e5c31af7Sopenharmony_ci "%id_xy = OpVectorShuffle %type_vec2_u32 %idvec %idvec 0 1\n" 2558e5c31af7Sopenharmony_ci "%coord = OpBitcast %type_vec2_i32 %id_xy\n" 2559e5c31af7Sopenharmony_ci "%value = OpImageRead ${sampled_type_vec4} %src_image %coord ${read_extend_operand}\n" 2560e5c31af7Sopenharmony_ci " OpImageWrite %dst_image %coord %value ${write_extend_operand}\n" 2561e5c31af7Sopenharmony_ci " OpReturn\n" 2562e5c31af7Sopenharmony_ci " OpFunctionEnd\n"); 2563e5c31af7Sopenharmony_ci 2564e5c31af7Sopenharmony_ci const auto testedFormat = mapVkFormat(isWriteTest() ? m_writeFormat : m_readFormat); 2565e5c31af7Sopenharmony_ci const bool isSigned = (getTextureChannelClass(testedFormat.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER); 2566e5c31af7Sopenharmony_ci 2567e5c31af7Sopenharmony_ci const auto isRead64 = is64BitIntegerFormat(m_readFormat); 2568e5c31af7Sopenharmony_ci const auto isWrite64 = is64BitIntegerFormat(m_writeFormat); 2569e5c31af7Sopenharmony_ci DE_ASSERT(isRead64 == isWrite64); 2570e5c31af7Sopenharmony_ci 2571e5c31af7Sopenharmony_ci const bool using64Bits = (isRead64 || isWrite64); 2572e5c31af7Sopenharmony_ci 2573e5c31af7Sopenharmony_ci // Additional capabilities when needed. 2574e5c31af7Sopenharmony_ci std::string capability; 2575e5c31af7Sopenharmony_ci std::string extension; 2576e5c31af7Sopenharmony_ci std::string extraTypes; 2577e5c31af7Sopenharmony_ci 2578e5c31af7Sopenharmony_ci if (using64Bits) 2579e5c31af7Sopenharmony_ci { 2580e5c31af7Sopenharmony_ci extension += "OpExtension \"SPV_EXT_shader_image_int64\"\n"; 2581e5c31af7Sopenharmony_ci capability += 2582e5c31af7Sopenharmony_ci "OpCapability Int64\n" 2583e5c31af7Sopenharmony_ci "OpCapability Int64ImageEXT\n" 2584e5c31af7Sopenharmony_ci ; 2585e5c31af7Sopenharmony_ci extraTypes += 2586e5c31af7Sopenharmony_ci "%type_i64 = OpTypeInt 64 1\n" 2587e5c31af7Sopenharmony_ci "%type_u64 = OpTypeInt 64 0\n" 2588e5c31af7Sopenharmony_ci "%type_vec3_i64 = OpTypeVector %type_i64 3\n" 2589e5c31af7Sopenharmony_ci "%type_vec3_u64 = OpTypeVector %type_u64 3\n" 2590e5c31af7Sopenharmony_ci "%type_vec4_i64 = OpTypeVector %type_i64 4\n" 2591e5c31af7Sopenharmony_ci "%type_vec4_u64 = OpTypeVector %type_u64 4\n" 2592e5c31af7Sopenharmony_ci ; 2593e5c31af7Sopenharmony_ci } 2594e5c31af7Sopenharmony_ci 2595e5c31af7Sopenharmony_ci std::string relaxed = ""; 2596e5c31af7Sopenharmony_ci if (m_relaxedPrecision) 2597e5c31af7Sopenharmony_ci relaxed += "OpDecorate %src_image_ptr RelaxedPrecision\n"; 2598e5c31af7Sopenharmony_ci 2599e5c31af7Sopenharmony_ci // Sampled type depends on the format sign and mismatch force flag. 2600e5c31af7Sopenharmony_ci const bool signedSampleType = ((isSigned && !m_operandForce) || (!isSigned && m_operandForce)); 2601e5c31af7Sopenharmony_ci const std::string bits = (using64Bits ? "64" : "32"); 2602e5c31af7Sopenharmony_ci const std::string sampledTypePostfix = (signedSampleType ? "i" : "u") + bits; 2603e5c31af7Sopenharmony_ci const std::string extendOperandStr = (isSigned ? "SignExtend" : "ZeroExtend"); 2604e5c31af7Sopenharmony_ci 2605e5c31af7Sopenharmony_ci std::map<std::string, std::string> specializations 2606e5c31af7Sopenharmony_ci { 2607e5c31af7Sopenharmony_ci { "image_type_id", "%type_image" }, 2608e5c31af7Sopenharmony_ci { "image_uni_ptr_type_id", "%type_ptr_uniform_const_image" }, 2609e5c31af7Sopenharmony_ci { "image_var_id", "%src_image_ptr" }, 2610e5c31af7Sopenharmony_ci { "image_id", "%src_image" }, 2611e5c31af7Sopenharmony_ci { "capability", capability }, 2612e5c31af7Sopenharmony_ci { "extension", extension }, 2613e5c31af7Sopenharmony_ci { "extra_types", extraTypes }, 2614e5c31af7Sopenharmony_ci { "relaxed_precision", relaxed }, 2615e5c31af7Sopenharmony_ci { "image_format", getSpirvFormat(m_readFormat) }, 2616e5c31af7Sopenharmony_ci { "sampled_type", (std::string("%type_") + sampledTypePostfix) }, 2617e5c31af7Sopenharmony_ci { "sampled_type_vec4", (std::string("%type_vec4_") + sampledTypePostfix) }, 2618e5c31af7Sopenharmony_ci { "read_extend_operand", (!isWriteTest() ? extendOperandStr : "") }, 2619e5c31af7Sopenharmony_ci { "write_extend_operand", (isWriteTest() ? extendOperandStr : "") }, 2620e5c31af7Sopenharmony_ci }; 2621e5c31af7Sopenharmony_ci 2622e5c31af7Sopenharmony_ci SpirvVersion spirvVersion = SPIRV_VERSION_1_4; 2623e5c31af7Sopenharmony_ci bool allowSpirv14 = true; 2624e5c31af7Sopenharmony_ci if (m_extendTestType == ExtendTestType::WRITE_NONTEMPORAL) 2625e5c31af7Sopenharmony_ci { 2626e5c31af7Sopenharmony_ci spirvVersion = SPIRV_VERSION_1_6; 2627e5c31af7Sopenharmony_ci allowSpirv14 = false; 2628e5c31af7Sopenharmony_ci specializations["write_extend_operand"] = "Nontemporal"; 2629e5c31af7Sopenharmony_ci } 2630e5c31af7Sopenharmony_ci 2631e5c31af7Sopenharmony_ci // Addidtional parametrization is needed for a case when source and destination textures have same format 2632e5c31af7Sopenharmony_ci tcu::StringTemplate imageTypeTemplate( 2633e5c31af7Sopenharmony_ci "${image_type_id} = OpTypeImage ${sampled_type} 2D 0 0 0 2 ${image_format}\n"); 2634e5c31af7Sopenharmony_ci tcu::StringTemplate imageUniformTypeTemplate( 2635e5c31af7Sopenharmony_ci "${image_uni_ptr_type_id} = OpTypePointer UniformConstant ${image_type_id}\n"); 2636e5c31af7Sopenharmony_ci tcu::StringTemplate imageVariablesTemplate( 2637e5c31af7Sopenharmony_ci "${image_var_id} = OpVariable ${image_uni_ptr_type_id} UniformConstant\n"); 2638e5c31af7Sopenharmony_ci tcu::StringTemplate imageLoadTemplate( 2639e5c31af7Sopenharmony_ci "${image_id} = OpLoad ${image_type_id} ${image_var_id}\n"); 2640e5c31af7Sopenharmony_ci 2641e5c31af7Sopenharmony_ci std::string imageTypes; 2642e5c31af7Sopenharmony_ci std::string imageUniformTypes; 2643e5c31af7Sopenharmony_ci std::string imageVariables; 2644e5c31af7Sopenharmony_ci std::string imageLoad; 2645e5c31af7Sopenharmony_ci 2646e5c31af7Sopenharmony_ci // If input image format is the same as output there is less spir-v definitions 2647e5c31af7Sopenharmony_ci if (m_readFormat == m_writeFormat) 2648e5c31af7Sopenharmony_ci { 2649e5c31af7Sopenharmony_ci imageTypes = imageTypeTemplate.specialize(specializations); 2650e5c31af7Sopenharmony_ci imageUniformTypes = imageUniformTypeTemplate.specialize(specializations); 2651e5c31af7Sopenharmony_ci imageVariables = imageVariablesTemplate.specialize(specializations); 2652e5c31af7Sopenharmony_ci imageLoad = imageLoadTemplate.specialize(specializations); 2653e5c31af7Sopenharmony_ci 2654e5c31af7Sopenharmony_ci specializations["image_var_id"] = "%dst_image_ptr"; 2655e5c31af7Sopenharmony_ci specializations["image_id"] = "%dst_image"; 2656e5c31af7Sopenharmony_ci imageVariables += imageVariablesTemplate.specialize(specializations); 2657e5c31af7Sopenharmony_ci imageLoad += imageLoadTemplate.specialize(specializations); 2658e5c31af7Sopenharmony_ci } 2659e5c31af7Sopenharmony_ci else 2660e5c31af7Sopenharmony_ci { 2661e5c31af7Sopenharmony_ci specializations["image_type_id"] = "%type_src_image"; 2662e5c31af7Sopenharmony_ci specializations["image_uni_ptr_type_id"] = "%type_ptr_uniform_const_src_image"; 2663e5c31af7Sopenharmony_ci imageTypes = imageTypeTemplate.specialize(specializations); 2664e5c31af7Sopenharmony_ci imageUniformTypes = imageUniformTypeTemplate.specialize(specializations); 2665e5c31af7Sopenharmony_ci imageVariables = imageVariablesTemplate.specialize(specializations); 2666e5c31af7Sopenharmony_ci imageLoad = imageLoadTemplate.specialize(specializations); 2667e5c31af7Sopenharmony_ci 2668e5c31af7Sopenharmony_ci specializations["image_format"] = getSpirvFormat(m_writeFormat); 2669e5c31af7Sopenharmony_ci specializations["image_type_id"] = "%type_dst_image"; 2670e5c31af7Sopenharmony_ci specializations["image_uni_ptr_type_id"] = "%type_ptr_uniform_const_dst_image"; 2671e5c31af7Sopenharmony_ci specializations["image_var_id"] = "%dst_image_ptr"; 2672e5c31af7Sopenharmony_ci specializations["image_id"] = "%dst_image"; 2673e5c31af7Sopenharmony_ci imageTypes += imageTypeTemplate.specialize(specializations); 2674e5c31af7Sopenharmony_ci imageUniformTypes += imageUniformTypeTemplate.specialize(specializations); 2675e5c31af7Sopenharmony_ci imageVariables += imageVariablesTemplate.specialize(specializations); 2676e5c31af7Sopenharmony_ci imageLoad += imageLoadTemplate.specialize(specializations); 2677e5c31af7Sopenharmony_ci } 2678e5c31af7Sopenharmony_ci 2679e5c31af7Sopenharmony_ci specializations["image_types"] = imageTypes; 2680e5c31af7Sopenharmony_ci specializations["image_uniforms"] = imageUniformTypes; 2681e5c31af7Sopenharmony_ci specializations["image_variables"] = imageVariables; 2682e5c31af7Sopenharmony_ci specializations["image_load"] = imageLoad; 2683e5c31af7Sopenharmony_ci 2684e5c31af7Sopenharmony_ci // Specialize whole shader and add it to program collection 2685e5c31af7Sopenharmony_ci programCollection.spirvAsmSources.add("comp") << shaderTemplate.specialize(specializations) 2686e5c31af7Sopenharmony_ci << vk::SpirVAsmBuildOptions(programCollection.usedVulkanVersion, spirvVersion, allowSpirv14); 2687e5c31af7Sopenharmony_ci} 2688e5c31af7Sopenharmony_ci 2689e5c31af7Sopenharmony_ciTestInstance* ImageExtendOperandTest::createInstance(Context& context) const 2690e5c31af7Sopenharmony_ci{ 2691e5c31af7Sopenharmony_ci return new ImageExtendOperandTestInstance(context, m_texture, m_readFormat, m_writeFormat, m_relaxedPrecision); 2692e5c31af7Sopenharmony_ci} 2693e5c31af7Sopenharmony_ci 2694e5c31af7Sopenharmony_cistatic const Texture s_textures[] = 2695e5c31af7Sopenharmony_ci{ 2696e5c31af7Sopenharmony_ci Texture(IMAGE_TYPE_1D, tcu::IVec3(64, 1, 1), 1), 2697e5c31af7Sopenharmony_ci Texture(IMAGE_TYPE_1D_ARRAY, tcu::IVec3(64, 1, 1), 8), 2698e5c31af7Sopenharmony_ci Texture(IMAGE_TYPE_2D, tcu::IVec3(64, 64, 1), 1), 2699e5c31af7Sopenharmony_ci Texture(IMAGE_TYPE_2D_ARRAY, tcu::IVec3(64, 64, 1), 8), 2700e5c31af7Sopenharmony_ci Texture(IMAGE_TYPE_3D, tcu::IVec3(64, 64, 8), 1), 2701e5c31af7Sopenharmony_ci Texture(IMAGE_TYPE_CUBE, tcu::IVec3(64, 64, 1), 6), 2702e5c31af7Sopenharmony_ci Texture(IMAGE_TYPE_CUBE_ARRAY, tcu::IVec3(64, 64, 1), 2*6), 2703e5c31af7Sopenharmony_ci Texture(IMAGE_TYPE_BUFFER, tcu::IVec3(64, 1, 1), 1), 2704e5c31af7Sopenharmony_ci}; 2705e5c31af7Sopenharmony_ci 2706e5c31af7Sopenharmony_ciconst Texture& getTestTexture (const ImageType imageType) 2707e5c31af7Sopenharmony_ci{ 2708e5c31af7Sopenharmony_ci for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx) 2709e5c31af7Sopenharmony_ci if (s_textures[textureNdx].type() == imageType) 2710e5c31af7Sopenharmony_ci return s_textures[textureNdx]; 2711e5c31af7Sopenharmony_ci 2712e5c31af7Sopenharmony_ci DE_FATAL("Internal error"); 2713e5c31af7Sopenharmony_ci return s_textures[0]; 2714e5c31af7Sopenharmony_ci} 2715e5c31af7Sopenharmony_ci 2716e5c31af7Sopenharmony_cistatic const VkFormat s_formats[] = 2717e5c31af7Sopenharmony_ci{ 2718e5c31af7Sopenharmony_ci VK_FORMAT_R32G32B32A32_SFLOAT, 2719e5c31af7Sopenharmony_ci VK_FORMAT_R16G16B16A16_SFLOAT, 2720e5c31af7Sopenharmony_ci VK_FORMAT_R32_SFLOAT, 2721e5c31af7Sopenharmony_ci 2722e5c31af7Sopenharmony_ci VK_FORMAT_R32G32B32A32_UINT, 2723e5c31af7Sopenharmony_ci VK_FORMAT_R16G16B16A16_UINT, 2724e5c31af7Sopenharmony_ci VK_FORMAT_R8G8B8A8_UINT, 2725e5c31af7Sopenharmony_ci VK_FORMAT_R32_UINT, 2726e5c31af7Sopenharmony_ci 2727e5c31af7Sopenharmony_ci VK_FORMAT_R32G32B32A32_SINT, 2728e5c31af7Sopenharmony_ci VK_FORMAT_R16G16B16A16_SINT, 2729e5c31af7Sopenharmony_ci VK_FORMAT_R8G8B8A8_SINT, 2730e5c31af7Sopenharmony_ci VK_FORMAT_R32_SINT, 2731e5c31af7Sopenharmony_ci 2732e5c31af7Sopenharmony_ci VK_FORMAT_R8G8B8A8_UNORM, 2733e5c31af7Sopenharmony_ci 2734e5c31af7Sopenharmony_ci VK_FORMAT_B8G8R8A8_UNORM, 2735e5c31af7Sopenharmony_ci VK_FORMAT_B8G8R8A8_UINT, 2736e5c31af7Sopenharmony_ci 2737e5c31af7Sopenharmony_ci VK_FORMAT_R8G8B8A8_SNORM, 2738e5c31af7Sopenharmony_ci 2739e5c31af7Sopenharmony_ci VK_FORMAT_B10G11R11_UFLOAT_PACK32, 2740e5c31af7Sopenharmony_ci 2741e5c31af7Sopenharmony_ci VK_FORMAT_R32G32_SFLOAT, 2742e5c31af7Sopenharmony_ci VK_FORMAT_R16G16_SFLOAT, 2743e5c31af7Sopenharmony_ci VK_FORMAT_R16_SFLOAT, 2744e5c31af7Sopenharmony_ci 2745e5c31af7Sopenharmony_ci VK_FORMAT_A2B10G10R10_UINT_PACK32, 2746e5c31af7Sopenharmony_ci VK_FORMAT_R32G32_UINT, 2747e5c31af7Sopenharmony_ci VK_FORMAT_R16G16_UINT, 2748e5c31af7Sopenharmony_ci VK_FORMAT_R16_UINT, 2749e5c31af7Sopenharmony_ci VK_FORMAT_R8G8_UINT, 2750e5c31af7Sopenharmony_ci VK_FORMAT_R8_UINT, 2751e5c31af7Sopenharmony_ci 2752e5c31af7Sopenharmony_ci VK_FORMAT_R32G32_SINT, 2753e5c31af7Sopenharmony_ci VK_FORMAT_R16G16_SINT, 2754e5c31af7Sopenharmony_ci VK_FORMAT_R16_SINT, 2755e5c31af7Sopenharmony_ci VK_FORMAT_R8G8_SINT, 2756e5c31af7Sopenharmony_ci VK_FORMAT_R8_SINT, 2757e5c31af7Sopenharmony_ci 2758e5c31af7Sopenharmony_ci VK_FORMAT_A2B10G10R10_UNORM_PACK32, 2759e5c31af7Sopenharmony_ci VK_FORMAT_R16G16B16A16_UNORM, 2760e5c31af7Sopenharmony_ci VK_FORMAT_R16G16B16A16_SNORM, 2761e5c31af7Sopenharmony_ci VK_FORMAT_R16G16_UNORM, 2762e5c31af7Sopenharmony_ci VK_FORMAT_R16_UNORM, 2763e5c31af7Sopenharmony_ci VK_FORMAT_R8G8_UNORM, 2764e5c31af7Sopenharmony_ci VK_FORMAT_R8_UNORM, 2765e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 2766e5c31af7Sopenharmony_ci VK_FORMAT_A8_UNORM_KHR, 2767e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 2768e5c31af7Sopenharmony_ci 2769e5c31af7Sopenharmony_ci VK_FORMAT_R16G16_SNORM, 2770e5c31af7Sopenharmony_ci VK_FORMAT_R16_SNORM, 2771e5c31af7Sopenharmony_ci VK_FORMAT_R8G8_SNORM, 2772e5c31af7Sopenharmony_ci VK_FORMAT_R8_SNORM, 2773e5c31af7Sopenharmony_ci 2774e5c31af7Sopenharmony_ci VK_FORMAT_R10X6_UNORM_PACK16, 2775e5c31af7Sopenharmony_ci VK_FORMAT_R10X6G10X6_UNORM_2PACK16, 2776e5c31af7Sopenharmony_ci VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16, 2777e5c31af7Sopenharmony_ci 2778e5c31af7Sopenharmony_ci VK_FORMAT_R4G4_UNORM_PACK8, 2779e5c31af7Sopenharmony_ci VK_FORMAT_R4G4B4A4_UNORM_PACK16, 2780e5c31af7Sopenharmony_ci VK_FORMAT_B4G4R4A4_UNORM_PACK16, 2781e5c31af7Sopenharmony_ci VK_FORMAT_R5G6B5_UNORM_PACK16, 2782e5c31af7Sopenharmony_ci VK_FORMAT_B5G6R5_UNORM_PACK16, 2783e5c31af7Sopenharmony_ci VK_FORMAT_R5G5B5A1_UNORM_PACK16, 2784e5c31af7Sopenharmony_ci VK_FORMAT_B5G5R5A1_UNORM_PACK16, 2785e5c31af7Sopenharmony_ci VK_FORMAT_A1R5G5B5_UNORM_PACK16, 2786e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 2787e5c31af7Sopenharmony_ci VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR, 2788e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 2789e5c31af7Sopenharmony_ci 2790e5c31af7Sopenharmony_ci VK_FORMAT_B8G8R8A8_SNORM, 2791e5c31af7Sopenharmony_ci VK_FORMAT_B8G8R8A8_SINT, 2792e5c31af7Sopenharmony_ci VK_FORMAT_A8B8G8R8_UNORM_PACK32, 2793e5c31af7Sopenharmony_ci VK_FORMAT_A8B8G8R8_SNORM_PACK32, 2794e5c31af7Sopenharmony_ci VK_FORMAT_A8B8G8R8_UINT_PACK32, 2795e5c31af7Sopenharmony_ci VK_FORMAT_A8B8G8R8_SINT_PACK32, 2796e5c31af7Sopenharmony_ci VK_FORMAT_A2R10G10B10_UNORM_PACK32, 2797e5c31af7Sopenharmony_ci VK_FORMAT_A2R10G10B10_SNORM_PACK32, 2798e5c31af7Sopenharmony_ci VK_FORMAT_A2R10G10B10_UINT_PACK32, 2799e5c31af7Sopenharmony_ci VK_FORMAT_A2R10G10B10_SINT_PACK32, 2800e5c31af7Sopenharmony_ci VK_FORMAT_A2B10G10R10_SNORM_PACK32, 2801e5c31af7Sopenharmony_ci VK_FORMAT_A2B10G10R10_SINT_PACK32, 2802e5c31af7Sopenharmony_ci VK_FORMAT_R32G32B32_UINT, 2803e5c31af7Sopenharmony_ci VK_FORMAT_R32G32B32_SINT, 2804e5c31af7Sopenharmony_ci VK_FORMAT_R32G32B32_SFLOAT, 2805e5c31af7Sopenharmony_ci VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, 2806e5c31af7Sopenharmony_ci 2807e5c31af7Sopenharmony_ci VK_FORMAT_R8G8_SRGB, 2808e5c31af7Sopenharmony_ci VK_FORMAT_R8G8B8_SRGB, 2809e5c31af7Sopenharmony_ci VK_FORMAT_B8G8R8_SRGB, 2810e5c31af7Sopenharmony_ci VK_FORMAT_R8G8B8A8_SRGB, 2811e5c31af7Sopenharmony_ci VK_FORMAT_B8G8R8A8_SRGB, 2812e5c31af7Sopenharmony_ci VK_FORMAT_A8B8G8R8_SRGB_PACK32 2813e5c31af7Sopenharmony_ci}; 2814e5c31af7Sopenharmony_ci 2815e5c31af7Sopenharmony_cistatic const VkFormat s_formatsThreeComponent[] = 2816e5c31af7Sopenharmony_ci{ 2817e5c31af7Sopenharmony_ci VK_FORMAT_R8G8B8_UINT, 2818e5c31af7Sopenharmony_ci VK_FORMAT_R8G8B8_SINT, 2819e5c31af7Sopenharmony_ci VK_FORMAT_R8G8B8_UNORM, 2820e5c31af7Sopenharmony_ci VK_FORMAT_R8G8B8_SNORM, 2821e5c31af7Sopenharmony_ci VK_FORMAT_R16G16B16_UINT, 2822e5c31af7Sopenharmony_ci VK_FORMAT_R16G16B16_SINT, 2823e5c31af7Sopenharmony_ci VK_FORMAT_R16G16B16_UNORM, 2824e5c31af7Sopenharmony_ci VK_FORMAT_R16G16B16_SNORM, 2825e5c31af7Sopenharmony_ci VK_FORMAT_R16G16B16_SFLOAT, 2826e5c31af7Sopenharmony_ci VK_FORMAT_R32G32B32_UINT, 2827e5c31af7Sopenharmony_ci VK_FORMAT_R32G32B32_SINT, 2828e5c31af7Sopenharmony_ci VK_FORMAT_R32G32B32_SFLOAT, 2829e5c31af7Sopenharmony_ci}; 2830e5c31af7Sopenharmony_ci 2831e5c31af7Sopenharmony_cistatic const VkImageTiling s_tilings[] = { 2832e5c31af7Sopenharmony_ci VK_IMAGE_TILING_OPTIMAL, 2833e5c31af7Sopenharmony_ci VK_IMAGE_TILING_LINEAR, 2834e5c31af7Sopenharmony_ci}; 2835e5c31af7Sopenharmony_ci 2836e5c31af7Sopenharmony_ciconst char* tilingSuffix(VkImageTiling tiling) { 2837e5c31af7Sopenharmony_ci switch (tiling) { 2838e5c31af7Sopenharmony_ci case VK_IMAGE_TILING_OPTIMAL: 2839e5c31af7Sopenharmony_ci return ""; 2840e5c31af7Sopenharmony_ci case VK_IMAGE_TILING_LINEAR: 2841e5c31af7Sopenharmony_ci return "_linear"; 2842e5c31af7Sopenharmony_ci default: 2843e5c31af7Sopenharmony_ci return "unknown"; 2844e5c31af7Sopenharmony_ci } 2845e5c31af7Sopenharmony_ci} 2846e5c31af7Sopenharmony_ci 2847e5c31af7Sopenharmony_ci} // anonymous ns 2848e5c31af7Sopenharmony_ci 2849e5c31af7Sopenharmony_citcu::TestCaseGroup* createImageStoreTests (tcu::TestContext& testCtx) 2850e5c31af7Sopenharmony_ci{ 2851e5c31af7Sopenharmony_ci // Plain imageStore() cases 2852e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "store")); 2853e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> testGroupWithFormat(new tcu::TestCaseGroup(testCtx, "with_format", "Declare a format layout qualifier for write images")); 2854e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> testGroupWithoutFormat(new tcu::TestCaseGroup(testCtx, "without_format", "Do not declare a format layout qualifier for write images")); 2855e5c31af7Sopenharmony_ci 2856e5c31af7Sopenharmony_ci for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx) 2857e5c31af7Sopenharmony_ci { 2858e5c31af7Sopenharmony_ci const Texture& texture = s_textures[textureNdx]; 2859e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> groupWithFormatByImageViewType (new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str())); 2860e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> groupWithoutFormatByImageViewType (new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str())); 2861e5c31af7Sopenharmony_ci const bool isLayered = (texture.numLayers() > 1); 2862e5c31af7Sopenharmony_ci 2863e5c31af7Sopenharmony_ci for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++formatNdx) 2864e5c31af7Sopenharmony_ci { 2865e5c31af7Sopenharmony_ci for (int tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(s_tilings); tilingNdx++) 2866e5c31af7Sopenharmony_ci { 2867e5c31af7Sopenharmony_ci const bool hasSpirvFmt = hasSpirvFormat(s_formats[formatNdx]); 2868e5c31af7Sopenharmony_ci const char* suffix = tilingSuffix(s_tilings[tilingNdx]); 2869e5c31af7Sopenharmony_ci 2870e5c31af7Sopenharmony_ci if (hasSpirvFmt) 2871e5c31af7Sopenharmony_ci { 2872e5c31af7Sopenharmony_ci groupWithFormatByImageViewType->addChild( new StoreTest(testCtx, getFormatShortString(s_formats[formatNdx]) + suffix, texture, s_formats[formatNdx], s_tilings[tilingNdx])); 2873e5c31af7Sopenharmony_ci // Additional tests where the shader uses constant data for imageStore. 2874e5c31af7Sopenharmony_ci groupWithFormatByImageViewType->addChild(new StoreTest(testCtx, getFormatShortString(s_formats[formatNdx]) + "_constant" + suffix, texture, s_formats[formatNdx], s_tilings[tilingNdx], StoreTest::FLAG_DECLARE_IMAGE_FORMAT_IN_SHADER | StoreTest::FLAG_STORE_CONSTANT_VALUE)); 2875e5c31af7Sopenharmony_ci } 2876e5c31af7Sopenharmony_ci groupWithoutFormatByImageViewType->addChild(new StoreTest(testCtx, getFormatShortString(s_formats[formatNdx]) + suffix, texture, s_formats[formatNdx], s_tilings[tilingNdx], 0)); 2877e5c31af7Sopenharmony_ci 2878e5c31af7Sopenharmony_ci if (isLayered && hasSpirvFmt) 2879e5c31af7Sopenharmony_ci groupWithFormatByImageViewType->addChild(new StoreTest(testCtx, getFormatShortString(s_formats[formatNdx]) + "_single_layer" + suffix, 2880e5c31af7Sopenharmony_ci texture, s_formats[formatNdx], VK_IMAGE_TILING_OPTIMAL, 2881e5c31af7Sopenharmony_ci StoreTest::FLAG_SINGLE_LAYER_BIND | StoreTest::FLAG_DECLARE_IMAGE_FORMAT_IN_SHADER)); 2882e5c31af7Sopenharmony_ci 2883e5c31af7Sopenharmony_ci if (texture.type() == IMAGE_TYPE_BUFFER) 2884e5c31af7Sopenharmony_ci { 2885e5c31af7Sopenharmony_ci if (hasSpirvFmt) 2886e5c31af7Sopenharmony_ci groupWithFormatByImageViewType->addChild(new StoreTest(testCtx, getFormatShortString(s_formats[formatNdx]) + "_minalign" + suffix, texture, s_formats[formatNdx], s_tilings[tilingNdx], StoreTest::FLAG_MINALIGN | StoreTest::FLAG_DECLARE_IMAGE_FORMAT_IN_SHADER)); 2887e5c31af7Sopenharmony_ci groupWithoutFormatByImageViewType->addChild(new StoreTest(testCtx, getFormatShortString(s_formats[formatNdx]) + "_minalign" + suffix, texture, s_formats[formatNdx], s_tilings[tilingNdx], StoreTest::FLAG_MINALIGN)); 2888e5c31af7Sopenharmony_ci } 2889e5c31af7Sopenharmony_ci } 2890e5c31af7Sopenharmony_ci } 2891e5c31af7Sopenharmony_ci 2892e5c31af7Sopenharmony_ci testGroupWithFormat->addChild(groupWithFormatByImageViewType.release()); 2893e5c31af7Sopenharmony_ci testGroupWithoutFormat->addChild(groupWithoutFormatByImageViewType.release()); 2894e5c31af7Sopenharmony_ci } 2895e5c31af7Sopenharmony_ci 2896e5c31af7Sopenharmony_ci testGroup->addChild(testGroupWithFormat.release()); 2897e5c31af7Sopenharmony_ci testGroup->addChild(testGroupWithoutFormat.release()); 2898e5c31af7Sopenharmony_ci 2899e5c31af7Sopenharmony_ci return testGroup.release(); 2900e5c31af7Sopenharmony_ci} 2901e5c31af7Sopenharmony_ci 2902e5c31af7Sopenharmony_citcu::TestCaseGroup* createImageLoadStoreTests (tcu::TestContext& testCtx) 2903e5c31af7Sopenharmony_ci{ 2904e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "load_store", "Cases with imageLoad() followed by imageStore()")); 2905e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> testGroupWithFormat(new tcu::TestCaseGroup(testCtx, "with_format", "Declare a format layout qualifier for read images")); 2906e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> testGroupWithoutFormat(new tcu::TestCaseGroup(testCtx, "without_format", "Do not declare a format layout qualifier for read images")); 2907e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> testGroupWithoutAnyFormat(new tcu::TestCaseGroup(testCtx, "without_any_format", "Do not declare a format layout qualifier for read or write images")); 2908e5c31af7Sopenharmony_ci 2909e5c31af7Sopenharmony_ci for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx) 2910e5c31af7Sopenharmony_ci { 2911e5c31af7Sopenharmony_ci const Texture& texture = s_textures[textureNdx]; 2912e5c31af7Sopenharmony_ci const auto imageTypeName = getImageTypeName(texture.type()); 2913e5c31af7Sopenharmony_ci const bool isLayered = (texture.numLayers() > 1); 2914e5c31af7Sopenharmony_ci 2915e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> groupWithFormatByImageViewType (new tcu::TestCaseGroup(testCtx, imageTypeName.c_str())); 2916e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> groupWithoutFormatByImageViewType (new tcu::TestCaseGroup(testCtx, imageTypeName.c_str())); 2917e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> groupWithoutAnyFormatByImageViewType (new tcu::TestCaseGroup(testCtx, imageTypeName.c_str())); 2918e5c31af7Sopenharmony_ci 2919e5c31af7Sopenharmony_ci for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++formatNdx) 2920e5c31af7Sopenharmony_ci { 2921e5c31af7Sopenharmony_ci const auto formatShortString = getFormatShortString(s_formats[formatNdx]); 2922e5c31af7Sopenharmony_ci const auto hasSpvFormat = hasSpirvFormat(s_formats[formatNdx]); 2923e5c31af7Sopenharmony_ci 2924e5c31af7Sopenharmony_ci for (int tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(s_tilings); tilingNdx++) 2925e5c31af7Sopenharmony_ci { 2926e5c31af7Sopenharmony_ci const char* suffix = tilingSuffix(s_tilings[tilingNdx]); 2927e5c31af7Sopenharmony_ci 2928e5c31af7Sopenharmony_ci if (hasSpvFormat) 2929e5c31af7Sopenharmony_ci { 2930e5c31af7Sopenharmony_ci groupWithFormatByImageViewType->addChild(new LoadStoreTest(testCtx, formatShortString + suffix, texture, s_formats[formatNdx], s_formats[formatNdx], s_tilings[tilingNdx])); 2931e5c31af7Sopenharmony_ci groupWithoutFormatByImageViewType->addChild(new LoadStoreTest(testCtx, formatShortString + suffix, texture, s_formats[formatNdx], s_formats[formatNdx], s_tilings[tilingNdx], LoadStoreTest::FLAG_DECLARE_FORMAT_IN_SHADER_WRITES)); 2932e5c31af7Sopenharmony_ci } 2933e5c31af7Sopenharmony_ci groupWithoutAnyFormatByImageViewType->addChild(new LoadStoreTest(testCtx, formatShortString + suffix, texture, s_formats[formatNdx], s_formats[formatNdx], s_tilings[tilingNdx], 0u)); 2934e5c31af7Sopenharmony_ci 2935e5c31af7Sopenharmony_ci if (isLayered && hasSpvFormat) 2936e5c31af7Sopenharmony_ci groupWithFormatByImageViewType->addChild(new LoadStoreTest(testCtx, formatShortString + "_single_layer" + suffix, 2937e5c31af7Sopenharmony_ci texture, s_formats[formatNdx], s_formats[formatNdx], s_tilings[tilingNdx], 2938e5c31af7Sopenharmony_ci LoadStoreTest::FLAG_SINGLE_LAYER_BIND | LoadStoreTest::FLAG_DECLARE_FORMAT_IN_SHADER_READS | LoadStoreTest::FLAG_DECLARE_FORMAT_IN_SHADER_WRITES)); 2939e5c31af7Sopenharmony_ci 2940e5c31af7Sopenharmony_ci if (texture.type() == IMAGE_TYPE_BUFFER) 2941e5c31af7Sopenharmony_ci { 2942e5c31af7Sopenharmony_ci if (hasSpvFormat) 2943e5c31af7Sopenharmony_ci { 2944e5c31af7Sopenharmony_ci groupWithFormatByImageViewType->addChild(new LoadStoreTest(testCtx, formatShortString + "_minalign" + suffix, texture, s_formats[formatNdx], s_formats[formatNdx], s_tilings[tilingNdx], LoadStoreTest::FLAG_MINALIGN | LoadStoreTest::FLAG_DECLARE_FORMAT_IN_SHADER_READS | LoadStoreTest::FLAG_DECLARE_FORMAT_IN_SHADER_WRITES)); 2945e5c31af7Sopenharmony_ci groupWithFormatByImageViewType->addChild(new LoadStoreTest(testCtx, formatShortString + "_minalign_uniform" + suffix, texture, s_formats[formatNdx], s_formats[formatNdx], s_tilings[tilingNdx], LoadStoreTest::FLAG_MINALIGN | LoadStoreTest::FLAG_DECLARE_FORMAT_IN_SHADER_READS | LoadStoreTest::FLAG_DECLARE_FORMAT_IN_SHADER_WRITES | LoadStoreTest::FLAG_UNIFORM_TEXEL_BUFFER)); 2946e5c31af7Sopenharmony_ci groupWithoutFormatByImageViewType->addChild(new LoadStoreTest(testCtx, formatShortString + "_minalign" + suffix, texture, s_formats[formatNdx], s_formats[formatNdx], s_tilings[tilingNdx], LoadStoreTest::FLAG_MINALIGN | LoadStoreTest::FLAG_DECLARE_FORMAT_IN_SHADER_WRITES)); 2947e5c31af7Sopenharmony_ci groupWithoutFormatByImageViewType->addChild(new LoadStoreTest(testCtx, formatShortString + "_minalign_uniform" + suffix, texture, s_formats[formatNdx], s_formats[formatNdx], s_tilings[tilingNdx], LoadStoreTest::FLAG_MINALIGN | LoadStoreTest::FLAG_UNIFORM_TEXEL_BUFFER | LoadStoreTest::FLAG_DECLARE_FORMAT_IN_SHADER_WRITES)); 2948e5c31af7Sopenharmony_ci } 2949e5c31af7Sopenharmony_ci groupWithoutAnyFormatByImageViewType->addChild(new LoadStoreTest(testCtx, formatShortString + "_minalign" + suffix, texture, s_formats[formatNdx], s_formats[formatNdx], s_tilings[tilingNdx], LoadStoreTest::FLAG_MINALIGN)); 2950e5c31af7Sopenharmony_ci groupWithoutAnyFormatByImageViewType->addChild(new LoadStoreTest(testCtx, formatShortString + "_minalign_uniform" + suffix, texture, s_formats[formatNdx], s_formats[formatNdx], s_tilings[tilingNdx], LoadStoreTest::FLAG_MINALIGN | LoadStoreTest::FLAG_UNIFORM_TEXEL_BUFFER)); 2951e5c31af7Sopenharmony_ci } 2952e5c31af7Sopenharmony_ci } 2953e5c31af7Sopenharmony_ci } 2954e5c31af7Sopenharmony_ci 2955e5c31af7Sopenharmony_ci if (texture.type() == IMAGE_TYPE_BUFFER) 2956e5c31af7Sopenharmony_ci { 2957e5c31af7Sopenharmony_ci for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_formatsThreeComponent); ++formatNdx) 2958e5c31af7Sopenharmony_ci { 2959e5c31af7Sopenharmony_ci const auto formatShortString = getFormatShortString(s_formatsThreeComponent[formatNdx]); 2960e5c31af7Sopenharmony_ci 2961e5c31af7Sopenharmony_ci for (int tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(s_tilings); tilingNdx++) 2962e5c31af7Sopenharmony_ci { 2963e5c31af7Sopenharmony_ci const char* suffix = tilingSuffix(s_tilings[tilingNdx]); 2964e5c31af7Sopenharmony_ci 2965e5c31af7Sopenharmony_ci groupWithoutFormatByImageViewType->addChild(new LoadStoreTest(testCtx, formatShortString + "_uniform" + suffix, texture, s_formatsThreeComponent[formatNdx], s_formatsThreeComponent[formatNdx], s_tilings[tilingNdx], LoadStoreTest::FLAG_UNIFORM_TEXEL_BUFFER | LoadStoreTest::FLAG_DECLARE_FORMAT_IN_SHADER_WRITES)); 2966e5c31af7Sopenharmony_ci groupWithoutFormatByImageViewType->addChild(new LoadStoreTest(testCtx, formatShortString + "_minalign_uniform" + suffix, texture, s_formatsThreeComponent[formatNdx], s_formatsThreeComponent[formatNdx], s_tilings[tilingNdx], LoadStoreTest::FLAG_MINALIGN | LoadStoreTest::FLAG_UNIFORM_TEXEL_BUFFER | LoadStoreTest::FLAG_DECLARE_FORMAT_IN_SHADER_WRITES)); 2967e5c31af7Sopenharmony_ci } 2968e5c31af7Sopenharmony_ci } 2969e5c31af7Sopenharmony_ci } 2970e5c31af7Sopenharmony_ci 2971e5c31af7Sopenharmony_ci testGroupWithFormat->addChild(groupWithFormatByImageViewType.release()); 2972e5c31af7Sopenharmony_ci testGroupWithoutFormat->addChild(groupWithoutFormatByImageViewType.release()); 2973e5c31af7Sopenharmony_ci testGroupWithoutAnyFormat->addChild(groupWithoutAnyFormatByImageViewType.release()); 2974e5c31af7Sopenharmony_ci } 2975e5c31af7Sopenharmony_ci 2976e5c31af7Sopenharmony_ci testGroup->addChild(testGroupWithFormat.release()); 2977e5c31af7Sopenharmony_ci testGroup->addChild(testGroupWithoutFormat.release()); 2978e5c31af7Sopenharmony_ci testGroup->addChild(testGroupWithoutAnyFormat.release()); 2979e5c31af7Sopenharmony_ci 2980e5c31af7Sopenharmony_ci return testGroup.release(); 2981e5c31af7Sopenharmony_ci} 2982e5c31af7Sopenharmony_ci 2983e5c31af7Sopenharmony_citcu::TestCaseGroup* createImageLoadStoreLodAMDTests (tcu::TestContext& testCtx) 2984e5c31af7Sopenharmony_ci{ 2985e5c31af7Sopenharmony_ci static const Texture textures[] = 2986e5c31af7Sopenharmony_ci { 2987e5c31af7Sopenharmony_ci Texture(IMAGE_TYPE_1D_ARRAY, tcu::IVec3(64, 1, 1), 8, 1, 6), 2988e5c31af7Sopenharmony_ci Texture(IMAGE_TYPE_1D, tcu::IVec3(64, 1, 1), 1, 1, 6), 2989e5c31af7Sopenharmony_ci Texture(IMAGE_TYPE_2D, tcu::IVec3(64, 64, 1), 1, 1, 6), 2990e5c31af7Sopenharmony_ci Texture(IMAGE_TYPE_2D_ARRAY, tcu::IVec3(64, 64, 1), 8, 1, 6), 2991e5c31af7Sopenharmony_ci Texture(IMAGE_TYPE_3D, tcu::IVec3(64, 64, 8), 1, 1, 6), 2992e5c31af7Sopenharmony_ci Texture(IMAGE_TYPE_CUBE, tcu::IVec3(64, 64, 1), 6, 1, 6), 2993e5c31af7Sopenharmony_ci Texture(IMAGE_TYPE_CUBE_ARRAY, tcu::IVec3(64, 64, 1), 2*6, 1, 6), 2994e5c31af7Sopenharmony_ci }; 2995e5c31af7Sopenharmony_ci 2996e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "load_store_lod", "Cases with imageLoad() followed by imageStore()")); 2997e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> testGroupWithFormat(new tcu::TestCaseGroup(testCtx, "with_format", "Declare a format layout qualifier for read images")); 2998e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> testGroupWithoutFormat(new tcu::TestCaseGroup(testCtx, "without_format", "Do not declare a format layout qualifier for read images")); 2999e5c31af7Sopenharmony_ci 3000e5c31af7Sopenharmony_ci for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(textures); ++textureNdx) 3001e5c31af7Sopenharmony_ci { 3002e5c31af7Sopenharmony_ci const Texture& texture = textures[textureNdx]; 3003e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> groupWithFormatByImageViewType (new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str())); 3004e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> groupWithoutFormatByImageViewType (new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str())); 3005e5c31af7Sopenharmony_ci const bool isLayered = (texture.numLayers() > 1); 3006e5c31af7Sopenharmony_ci 3007e5c31af7Sopenharmony_ci if (texture.type() == IMAGE_TYPE_BUFFER) 3008e5c31af7Sopenharmony_ci continue; 3009e5c31af7Sopenharmony_ci 3010e5c31af7Sopenharmony_ci for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++formatNdx) 3011e5c31af7Sopenharmony_ci { 3012e5c31af7Sopenharmony_ci // These tests always require a SPIR-V format for the write image, even if the read 3013e5c31af7Sopenharmony_ci // image is being used without a format. 3014e5c31af7Sopenharmony_ci if (!hasSpirvFormat(s_formats[formatNdx])) 3015e5c31af7Sopenharmony_ci continue; 3016e5c31af7Sopenharmony_ci 3017e5c31af7Sopenharmony_ci groupWithFormatByImageViewType->addChild(new LoadStoreTest(testCtx, getFormatShortString(s_formats[formatNdx]), texture, s_formats[formatNdx], s_formats[formatNdx], VK_IMAGE_TILING_OPTIMAL, (LoadStoreTest::FLAG_DECLARE_FORMAT_IN_SHADER_READS | LoadStoreTest::FLAG_DECLARE_FORMAT_IN_SHADER_WRITES), DE_TRUE)); 3018e5c31af7Sopenharmony_ci groupWithoutFormatByImageViewType->addChild(new LoadStoreTest(testCtx, getFormatShortString(s_formats[formatNdx]), texture, s_formats[formatNdx], s_formats[formatNdx], VK_IMAGE_TILING_OPTIMAL, LoadStoreTest::FLAG_DECLARE_FORMAT_IN_SHADER_WRITES, DE_TRUE)); 3019e5c31af7Sopenharmony_ci 3020e5c31af7Sopenharmony_ci if (isLayered) 3021e5c31af7Sopenharmony_ci groupWithFormatByImageViewType->addChild(new LoadStoreTest(testCtx, getFormatShortString(s_formats[formatNdx]) + "_single_layer", 3022e5c31af7Sopenharmony_ci texture, s_formats[formatNdx], s_formats[formatNdx], VK_IMAGE_TILING_OPTIMAL, 3023e5c31af7Sopenharmony_ci LoadStoreTest::FLAG_SINGLE_LAYER_BIND | LoadStoreTest::FLAG_DECLARE_FORMAT_IN_SHADER_READS | LoadStoreTest::FLAG_DECLARE_FORMAT_IN_SHADER_WRITES, DE_TRUE)); 3024e5c31af7Sopenharmony_ci } 3025e5c31af7Sopenharmony_ci 3026e5c31af7Sopenharmony_ci testGroupWithFormat->addChild(groupWithFormatByImageViewType.release()); 3027e5c31af7Sopenharmony_ci testGroupWithoutFormat->addChild(groupWithoutFormatByImageViewType.release()); 3028e5c31af7Sopenharmony_ci } 3029e5c31af7Sopenharmony_ci 3030e5c31af7Sopenharmony_ci testGroup->addChild(testGroupWithFormat.release()); 3031e5c31af7Sopenharmony_ci testGroup->addChild(testGroupWithoutFormat.release()); 3032e5c31af7Sopenharmony_ci 3033e5c31af7Sopenharmony_ci return testGroup.release(); 3034e5c31af7Sopenharmony_ci} 3035e5c31af7Sopenharmony_ci 3036e5c31af7Sopenharmony_citcu::TestCaseGroup* createImageFormatReinterpretTests (tcu::TestContext& testCtx) 3037e5c31af7Sopenharmony_ci{ 3038e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "format_reinterpret", "Cases with differing texture and image formats")); 3039e5c31af7Sopenharmony_ci 3040e5c31af7Sopenharmony_ci for (int textureNdx = 0; textureNdx < DE_LENGTH_OF_ARRAY(s_textures); ++textureNdx) 3041e5c31af7Sopenharmony_ci { 3042e5c31af7Sopenharmony_ci const Texture& texture = s_textures[textureNdx]; 3043e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> groupByImageViewType (new tcu::TestCaseGroup(testCtx, getImageTypeName(texture.type()).c_str())); 3044e5c31af7Sopenharmony_ci 3045e5c31af7Sopenharmony_ci for (int imageFormatNdx = 0; imageFormatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++imageFormatNdx) 3046e5c31af7Sopenharmony_ci for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_formats); ++formatNdx) 3047e5c31af7Sopenharmony_ci { 3048e5c31af7Sopenharmony_ci if (!hasSpirvFormat(s_formats[formatNdx])) 3049e5c31af7Sopenharmony_ci continue; 3050e5c31af7Sopenharmony_ci 3051e5c31af7Sopenharmony_ci const std::string caseName = getFormatShortString(s_formats[imageFormatNdx]) + "_" + getFormatShortString(s_formats[formatNdx]); 3052e5c31af7Sopenharmony_ci if (imageFormatNdx != formatNdx && formatsAreCompatible(s_formats[imageFormatNdx], s_formats[formatNdx])) 3053e5c31af7Sopenharmony_ci groupByImageViewType->addChild(new LoadStoreTest(testCtx, caseName, texture, s_formats[formatNdx], s_formats[imageFormatNdx], VK_IMAGE_TILING_OPTIMAL)); 3054e5c31af7Sopenharmony_ci } 3055e5c31af7Sopenharmony_ci testGroup->addChild(groupByImageViewType.release()); 3056e5c31af7Sopenharmony_ci } 3057e5c31af7Sopenharmony_ci 3058e5c31af7Sopenharmony_ci return testGroup.release(); 3059e5c31af7Sopenharmony_ci} 3060e5c31af7Sopenharmony_ci 3061e5c31af7Sopenharmony_cide::MovePtr<TestCase> createImageQualifierRestrictCase (tcu::TestContext& testCtx, const ImageType imageType, const std::string& name) 3062e5c31af7Sopenharmony_ci{ 3063e5c31af7Sopenharmony_ci const VkFormat format = VK_FORMAT_R32G32B32A32_UINT; 3064e5c31af7Sopenharmony_ci const Texture& texture = getTestTexture(imageType); 3065e5c31af7Sopenharmony_ci return de::MovePtr<TestCase>(new LoadStoreTest(testCtx, name, texture, format, format, VK_IMAGE_TILING_OPTIMAL, LoadStoreTest::FLAG_RESTRICT_IMAGES | LoadStoreTest::FLAG_DECLARE_FORMAT_IN_SHADER_READS | LoadStoreTest::FLAG_DECLARE_FORMAT_IN_SHADER_WRITES)); 3066e5c31af7Sopenharmony_ci} 3067e5c31af7Sopenharmony_ci 3068e5c31af7Sopenharmony_cinamespace 3069e5c31af7Sopenharmony_ci{ 3070e5c31af7Sopenharmony_ci 3071e5c31af7Sopenharmony_cibool relaxedOK(VkFormat format) 3072e5c31af7Sopenharmony_ci{ 3073e5c31af7Sopenharmony_ci tcu::IVec4 bitDepth = tcu::getTextureFormatBitDepth(mapVkFormat(format)); 3074e5c31af7Sopenharmony_ci int maxBitDepth = deMax32(deMax32(bitDepth[0], bitDepth[1]), deMax32(bitDepth[2], bitDepth[3])); 3075e5c31af7Sopenharmony_ci return maxBitDepth <= 16; 3076e5c31af7Sopenharmony_ci} 3077e5c31af7Sopenharmony_ci 3078e5c31af7Sopenharmony_ci// Get a format used for reading or writing in extension operand tests. These formats allow representing the shader sampled type to 3079e5c31af7Sopenharmony_ci// verify results from read or write operations. 3080e5c31af7Sopenharmony_ciVkFormat getShaderExtensionOperandFormat (bool isSigned, bool is64Bit) 3081e5c31af7Sopenharmony_ci{ 3082e5c31af7Sopenharmony_ci const VkFormat formats[] = 3083e5c31af7Sopenharmony_ci { 3084e5c31af7Sopenharmony_ci VK_FORMAT_R32G32B32A32_UINT, 3085e5c31af7Sopenharmony_ci VK_FORMAT_R32G32B32A32_SINT, 3086e5c31af7Sopenharmony_ci VK_FORMAT_R64_UINT, 3087e5c31af7Sopenharmony_ci VK_FORMAT_R64_SINT, 3088e5c31af7Sopenharmony_ci }; 3089e5c31af7Sopenharmony_ci return formats[2u * (is64Bit ? 1u : 0u) + (isSigned ? 1u : 0u)]; 3090e5c31af7Sopenharmony_ci} 3091e5c31af7Sopenharmony_ci 3092e5c31af7Sopenharmony_ci// INT or UINT format? 3093e5c31af7Sopenharmony_cibool isIntegralFormat (VkFormat format) 3094e5c31af7Sopenharmony_ci{ 3095e5c31af7Sopenharmony_ci return (isIntFormat(format) || isUintFormat(format)); 3096e5c31af7Sopenharmony_ci} 3097e5c31af7Sopenharmony_ci 3098e5c31af7Sopenharmony_ci// Return the list of formats used for the extension operand tests (SignExten/ZeroExtend). 3099e5c31af7Sopenharmony_cistd::vector<VkFormat> getExtensionOperandFormatList (void) 3100e5c31af7Sopenharmony_ci{ 3101e5c31af7Sopenharmony_ci std::vector<VkFormat> formatList; 3102e5c31af7Sopenharmony_ci 3103e5c31af7Sopenharmony_ci for (auto format : s_formats) 3104e5c31af7Sopenharmony_ci { 3105e5c31af7Sopenharmony_ci if (isIntegralFormat(format)) 3106e5c31af7Sopenharmony_ci formatList.push_back(format); 3107e5c31af7Sopenharmony_ci } 3108e5c31af7Sopenharmony_ci 3109e5c31af7Sopenharmony_ci formatList.push_back(VK_FORMAT_R64_SINT); 3110e5c31af7Sopenharmony_ci formatList.push_back(VK_FORMAT_R64_UINT); 3111e5c31af7Sopenharmony_ci 3112e5c31af7Sopenharmony_ci return formatList; 3113e5c31af7Sopenharmony_ci} 3114e5c31af7Sopenharmony_ci 3115e5c31af7Sopenharmony_ci} // anonymous 3116e5c31af7Sopenharmony_ci 3117e5c31af7Sopenharmony_citcu::TestCaseGroup* createImageExtendOperandsTests(tcu::TestContext& testCtx) 3118e5c31af7Sopenharmony_ci{ 3119e5c31af7Sopenharmony_ci using GroupPtr = de::MovePtr<tcu::TestCaseGroup>; 3120e5c31af7Sopenharmony_ci 3121e5c31af7Sopenharmony_ci GroupPtr testGroup(new tcu::TestCaseGroup(testCtx, "extend_operands_spirv1p4", "Cases with SignExtend and ZeroExtend")); 3122e5c31af7Sopenharmony_ci 3123e5c31af7Sopenharmony_ci const struct 3124e5c31af7Sopenharmony_ci { 3125e5c31af7Sopenharmony_ci ExtendTestType testType; 3126e5c31af7Sopenharmony_ci const char* name; 3127e5c31af7Sopenharmony_ci } testTypes[] = 3128e5c31af7Sopenharmony_ci { 3129e5c31af7Sopenharmony_ci { ExtendTestType::READ, "read" }, 3130e5c31af7Sopenharmony_ci { ExtendTestType::WRITE, "write" }, 3131e5c31af7Sopenharmony_ci }; 3132e5c31af7Sopenharmony_ci 3133e5c31af7Sopenharmony_ci const auto texture = Texture(IMAGE_TYPE_2D, tcu::IVec3(8, 8, 1), 1); 3134e5c31af7Sopenharmony_ci const auto formatList = getExtensionOperandFormatList(); 3135e5c31af7Sopenharmony_ci 3136e5c31af7Sopenharmony_ci for (const auto format : formatList) 3137e5c31af7Sopenharmony_ci { 3138e5c31af7Sopenharmony_ci const auto isInt = isIntFormat(format); 3139e5c31af7Sopenharmony_ci const auto isUint = isUintFormat(format); 3140e5c31af7Sopenharmony_ci const auto use64Bits = is64BitIntegerFormat(format); 3141e5c31af7Sopenharmony_ci 3142e5c31af7Sopenharmony_ci DE_ASSERT(isInt || isUint); 3143e5c31af7Sopenharmony_ci 3144e5c31af7Sopenharmony_ci GroupPtr formatGroup (new tcu::TestCaseGroup(testCtx, getFormatShortString(format).c_str())); 3145e5c31af7Sopenharmony_ci 3146e5c31af7Sopenharmony_ci for (const auto& testType : testTypes) 3147e5c31af7Sopenharmony_ci { 3148e5c31af7Sopenharmony_ci GroupPtr testTypeGroup (new tcu::TestCaseGroup(testCtx, testType.name)); 3149e5c31af7Sopenharmony_ci 3150e5c31af7Sopenharmony_ci for (int match = 0; match < 2; ++match) 3151e5c31af7Sopenharmony_ci { 3152e5c31af7Sopenharmony_ci const bool mismatched = (match == 1); 3153e5c31af7Sopenharmony_ci const char* matchGroupName = (mismatched ? "mismatched_sign" : "matched_sign"); 3154e5c31af7Sopenharmony_ci 3155e5c31af7Sopenharmony_ci // SPIR-V does not allow this kind of sampled type override. 3156e5c31af7Sopenharmony_ci if (mismatched && isUint) 3157e5c31af7Sopenharmony_ci continue; 3158e5c31af7Sopenharmony_ci 3159e5c31af7Sopenharmony_ci GroupPtr matchGroup (new tcu::TestCaseGroup(testCtx, matchGroupName)); 3160e5c31af7Sopenharmony_ci 3161e5c31af7Sopenharmony_ci for (int prec = 0; prec < 2; prec++) 3162e5c31af7Sopenharmony_ci { 3163e5c31af7Sopenharmony_ci const bool relaxedPrecision = (prec != 0); 3164e5c31af7Sopenharmony_ci 3165e5c31af7Sopenharmony_ci const char* precisionName = (relaxedPrecision ? "relaxed_precision" : "normal_precision"); 3166e5c31af7Sopenharmony_ci const auto signedOther = ((isInt && !mismatched) || (isUint && mismatched)); 3167e5c31af7Sopenharmony_ci const auto otherFormat = getShaderExtensionOperandFormat(signedOther, use64Bits); 3168e5c31af7Sopenharmony_ci const auto readFormat = (testType.testType == ExtendTestType::READ ? format : otherFormat); 3169e5c31af7Sopenharmony_ci const auto writeFormat = (testType.testType == ExtendTestType::WRITE ? format : otherFormat); 3170e5c31af7Sopenharmony_ci 3171e5c31af7Sopenharmony_ci if (relaxedPrecision && !relaxedOK(readFormat)) 3172e5c31af7Sopenharmony_ci continue; 3173e5c31af7Sopenharmony_ci 3174e5c31af7Sopenharmony_ci if (!hasSpirvFormat(readFormat) || !hasSpirvFormat(writeFormat)) 3175e5c31af7Sopenharmony_ci continue; 3176e5c31af7Sopenharmony_ci 3177e5c31af7Sopenharmony_ci matchGroup->addChild(new ImageExtendOperandTest(testCtx, precisionName, texture, readFormat, writeFormat, mismatched, relaxedPrecision, testType.testType)); 3178e5c31af7Sopenharmony_ci } 3179e5c31af7Sopenharmony_ci 3180e5c31af7Sopenharmony_ci testTypeGroup->addChild(matchGroup.release()); 3181e5c31af7Sopenharmony_ci } 3182e5c31af7Sopenharmony_ci 3183e5c31af7Sopenharmony_ci formatGroup->addChild(testTypeGroup.release()); 3184e5c31af7Sopenharmony_ci } 3185e5c31af7Sopenharmony_ci 3186e5c31af7Sopenharmony_ci testGroup->addChild(formatGroup.release()); 3187e5c31af7Sopenharmony_ci } 3188e5c31af7Sopenharmony_ci 3189e5c31af7Sopenharmony_ci return testGroup.release(); 3190e5c31af7Sopenharmony_ci} 3191e5c31af7Sopenharmony_ci 3192e5c31af7Sopenharmony_citcu::TestCaseGroup* createImageNontemporalOperandTests(tcu::TestContext& testCtx) 3193e5c31af7Sopenharmony_ci{ 3194e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "nontemporal_operand", "Cases with Nontemporal image operand for SPOIR-V 1.6")); 3195e5c31af7Sopenharmony_ci 3196e5c31af7Sopenharmony_ci const auto texture = Texture(IMAGE_TYPE_2D, tcu::IVec3(8, 8, 1), 1); 3197e5c31af7Sopenharmony_ci 3198e5c31af7Sopenharmony_ci // using just integer formats for tests so that ImageExtendOperandTest could be reused 3199e5c31af7Sopenharmony_ci const auto formatList = getExtensionOperandFormatList(); 3200e5c31af7Sopenharmony_ci 3201e5c31af7Sopenharmony_ci for (const auto format : formatList) 3202e5c31af7Sopenharmony_ci { 3203e5c31af7Sopenharmony_ci const std::string caseName = getFormatShortString(format); 3204e5c31af7Sopenharmony_ci const auto readFormat = format; 3205e5c31af7Sopenharmony_ci const auto writeFormat = getShaderExtensionOperandFormat(isIntFormat(format), is64BitIntegerFormat(format)); 3206e5c31af7Sopenharmony_ci 3207e5c31af7Sopenharmony_ci if (!hasSpirvFormat(readFormat) || !hasSpirvFormat(writeFormat)) 3208e5c31af7Sopenharmony_ci continue; 3209e5c31af7Sopenharmony_ci 3210e5c31af7Sopenharmony_ci // note: just testing OpImageWrite as OpImageRead is tested with addComputeImageSamplerTest 3211e5c31af7Sopenharmony_ci testGroup->addChild(new ImageExtendOperandTest(testCtx, caseName, texture, 3212e5c31af7Sopenharmony_ci readFormat, writeFormat, false, false, ExtendTestType::WRITE_NONTEMPORAL)); 3213e5c31af7Sopenharmony_ci } 3214e5c31af7Sopenharmony_ci 3215e5c31af7Sopenharmony_ci return testGroup.release(); 3216e5c31af7Sopenharmony_ci} 3217e5c31af7Sopenharmony_ci 3218e5c31af7Sopenharmony_ci} // image 3219e5c31af7Sopenharmony_ci} // vkt 3220