blob: cd195d4001ead9a2303a53e7e579950f7e624cbb [file] [log] [blame]
/*------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2016 The Khronos Group Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*//*!
* \file
* \brief Image Tests Utility Classes
*//*--------------------------------------------------------------------*/
#include "vktImageTestsUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
#include "tcuTextureUtil.hpp"
using namespace vk;
namespace vkt
{
namespace image
{
Buffer::Buffer (const DeviceInterface& vk,
const VkDevice device,
Allocator& allocator,
const VkBufferCreateInfo& bufferCreateInfo,
const MemoryRequirement memoryRequirement)
{
m_buffer = createBuffer(vk, device, &bufferCreateInfo);
m_allocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), memoryRequirement);
VK_CHECK(vk.bindBufferMemory(device, *m_buffer, m_allocation->getMemory(), m_allocation->getOffset()));
}
Image::Image (const DeviceInterface& vk,
const VkDevice device,
Allocator& allocator,
const VkImageCreateInfo& imageCreateInfo,
const MemoryRequirement memoryRequirement)
{
m_image = createImage(vk, device, &imageCreateInfo);
m_allocation = allocator.allocate(getImageMemoryRequirements(vk, device, *m_image), memoryRequirement);
VK_CHECK(vk.bindImageMemory(device, *m_image, m_allocation->getMemory(), m_allocation->getOffset()));
}
tcu::UVec3 getShaderGridSize (const ImageType imageType, const tcu::UVec3& imageSize)
{
switch (imageType)
{
case IMAGE_TYPE_1D:
case IMAGE_TYPE_BUFFER:
return tcu::UVec3(imageSize.x(), 1u, 1u);
case IMAGE_TYPE_1D_ARRAY:
return tcu::UVec3(imageSize.x(), imageSize.z(), 1u);
case IMAGE_TYPE_2D:
return tcu::UVec3(imageSize.x(), imageSize.y(), 1u);
case IMAGE_TYPE_2D_ARRAY:
case IMAGE_TYPE_3D:
return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z());
case IMAGE_TYPE_CUBE:
return tcu::UVec3(imageSize.x(), imageSize.y(), 6u);
case IMAGE_TYPE_CUBE_ARRAY:
return tcu::UVec3(imageSize.x(), imageSize.y(), 6u * imageSize.z());
default:
DE_FATAL("Unknown image type");
return tcu::UVec3(1u, 1u, 1u);
}
}
tcu::UVec3 getLayerSize (const ImageType imageType, const tcu::UVec3& imageSize)
{
switch (imageType)
{
case IMAGE_TYPE_1D:
case IMAGE_TYPE_1D_ARRAY:
case IMAGE_TYPE_BUFFER:
return tcu::UVec3(imageSize.x(), 1u, 1u);
case IMAGE_TYPE_2D:
case IMAGE_TYPE_2D_ARRAY:
case IMAGE_TYPE_CUBE:
case IMAGE_TYPE_CUBE_ARRAY:
return tcu::UVec3(imageSize.x(), imageSize.y(), 1u);
case IMAGE_TYPE_3D:
return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z());
default:
DE_FATAL("Unknown image type");
return tcu::UVec3(1u, 1u, 1u);
}
}
deUint32 getNumLayers (const ImageType imageType, const tcu::UVec3& imageSize)
{
switch (imageType)
{
case IMAGE_TYPE_1D:
case IMAGE_TYPE_2D:
case IMAGE_TYPE_3D:
case IMAGE_TYPE_BUFFER:
return 1u;
case IMAGE_TYPE_1D_ARRAY:
case IMAGE_TYPE_2D_ARRAY:
return imageSize.z();
case IMAGE_TYPE_CUBE:
return 6u;
case IMAGE_TYPE_CUBE_ARRAY:
return imageSize.z() * 6u;
default:
DE_FATAL("Unknown image type");
return 0u;
}
}
deUint32 getNumPixels (const ImageType imageType, const tcu::UVec3& imageSize)
{
const tcu::UVec3 gridSize = getShaderGridSize(imageType, imageSize);
return gridSize.x() * gridSize.y() * gridSize.z();
}
deUint32 getDimensions (const ImageType imageType)
{
switch (imageType)
{
case IMAGE_TYPE_1D:
case IMAGE_TYPE_BUFFER:
return 1u;
case IMAGE_TYPE_1D_ARRAY:
case IMAGE_TYPE_2D:
return 2u;
case IMAGE_TYPE_2D_ARRAY:
case IMAGE_TYPE_CUBE:
case IMAGE_TYPE_CUBE_ARRAY:
case IMAGE_TYPE_3D:
return 3u;
default:
DE_FATAL("Unknown image type");
return 0u;
}
}
deUint32 getLayerDimensions (const ImageType imageType)
{
switch (imageType)
{
case IMAGE_TYPE_1D:
case IMAGE_TYPE_BUFFER:
case IMAGE_TYPE_1D_ARRAY:
return 1u;
case IMAGE_TYPE_2D:
case IMAGE_TYPE_2D_ARRAY:
case IMAGE_TYPE_CUBE:
case IMAGE_TYPE_CUBE_ARRAY:
return 2u;
case IMAGE_TYPE_3D:
return 3u;
default:
DE_FATAL("Unknown image type");
return 0u;
}
}
VkBufferImageCopy makeBufferImageCopy (const VkExtent3D extent,
const deUint32 arraySize)
{
const VkBufferImageCopy copyParams =
{
0ull, // VkDeviceSize bufferOffset;
0u, // deUint32 bufferRowLength;
0u, // deUint32 bufferImageHeight;
makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, arraySize), // VkImageSubresourceLayers imageSubresource;
makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
extent, // VkExtent3D imageExtent;
};
return copyParams;
}
Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk,
const VkDevice device,
const VkPipelineLayout pipelineLayout,
const VkShaderModule shaderModule)
{
const VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
{
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
0u, // VkPipelineShaderStageCreateFlags flags;
VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
shaderModule, // VkShaderModule module;
"main", // const char* pName;
DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
};
const VkComputePipelineCreateInfo pipelineCreateInfo =
{
VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
0u, // VkPipelineCreateFlags flags;
pipelineShaderStageParams, // VkPipelineShaderStageCreateInfo stage;
pipelineLayout, // VkPipelineLayout layout;
DE_NULL, // VkPipeline basePipelineHandle;
0, // deInt32 basePipelineIndex;
};
return createComputePipeline(vk, device, DE_NULL , &pipelineCreateInfo);
}
Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
const VkDevice device,
const VkPipelineLayout pipelineLayout,
const VkRenderPass renderPass,
const VkShaderModule vertexModule,
const VkShaderModule fragmentModule,
const VkExtent2D renderSize,
const deUint32 colorAttachmentCount,
const bool dynamicSize)
{
std::vector<VkViewport> viewports;
std::vector<VkRect2D> scissors;
const VkViewport viewport = makeViewport(renderSize);
const VkRect2D scissor = makeRect2D(renderSize);
const VkFormat vertexFormatPosition = VK_FORMAT_R32G32B32A32_SFLOAT;
const deUint32 vertexSizePosition = tcu::getPixelSize(mapVkFormat(vertexFormatPosition));
const deUint32 vertexBufferOffsetPosition = 0u;
const deUint32 vertexDataStride = vertexSizePosition;
if (!dynamicSize)
{
viewports.push_back(viewport);
scissors.push_back(scissor);
}
const VkVertexInputBindingDescription vertexInputBindingDescription =
{
0u, // deUint32 binding;
vertexDataStride, // deUint32 stride;
VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
};
const VkVertexInputAttributeDescription vertexInputAttributeDescription =
{
0u, // deUint32 location;
0u, // deUint32 binding;
vertexFormatPosition, // VkFormat format;
vertexBufferOffsetPosition, // deUint32 offset;
};
const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
{
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
(VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
1u, // deUint32 vertexBindingDescriptionCount;
&vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1u, // deUint32 vertexAttributeDescriptionCount;
&vertexInputAttributeDescription // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
};
const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
{
VK_FALSE, // VkBool32 blendEnable;
VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
colorComponentsAll // VkColorComponentFlags colorWriteMask;
};
std::vector<VkPipelineColorBlendAttachmentState> colorAttachments (colorAttachmentCount, colorBlendAttachmentState);
const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
{
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
(VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
VK_FALSE, // VkBool32 logicOpEnable;
VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
(deUint32)colorAttachments.size(), // deUint32 attachmentCount;
colorAttachments.size() != 0 ? &colorAttachments[0] : DE_NULL, // const VkPipelineColorBlendAttachmentState* pAttachments;
{ 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4];
};
return vk::makeGraphicsPipeline(vk, // const DeviceInterface& vk
device, // const VkDevice device
pipelineLayout, // const VkPipelineLayout pipelineLayout
vertexModule, // const VkShaderModule vertexShaderModule
DE_NULL, // const VkShaderModule tessellationControlModule
DE_NULL, // const VkShaderModule tessellationEvalModule
DE_NULL, // const VkShaderModule geometryShaderModule
fragmentModule, // const VkShaderModule fragmentShaderModule
renderPass, // const VkRenderPass renderPass
viewports, // const std::vector<VkViewport>& viewports
scissors, // const std::vector<VkRect2D>& scissors
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
0u, // const deUint32 subpass
0u, // const deUint32 patchControlPoints
&vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
&pipelineColorBlendStateInfo); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
}
//! A single-subpass render pass.
Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
const VkDevice device,
const VkFormat inputFormat,
const VkFormat colorFormat)
{
const VkAttachmentReference inputAttachmentRef =
{
0u, // deUint32 attachment;
VK_IMAGE_LAYOUT_GENERAL // VkImageLayout layout;
};
const VkAttachmentReference colorAttachmentRef =
{
1u, // deUint32 attachment;
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
};
const VkSubpassDescription subpassDescription =
{
(VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
1u, // deUint32 inputAttachmentCount;
&inputAttachmentRef, // const VkAttachmentReference* pInputAttachments;
1u, // deUint32 colorAttachmentCount;
&colorAttachmentRef, // const VkAttachmentReference* pColorAttachments;
DE_NULL, // const VkAttachmentReference* pResolveAttachments;
DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
0u, // deUint32 preserveAttachmentCount;
DE_NULL // const deUint32* pPreserveAttachments;
};
const VkAttachmentDescription attachmentsDescriptions[] =
{
//inputAttachmentDescription,
{
(VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
inputFormat, // VkFormat format;
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp;
VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout initialLayout;
VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout finalLayout;
},
//colorAttachmentDescription
{
(VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
colorFormat, // VkFormat format;
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout finalLayout;
}
};
const VkRenderPassCreateInfo renderPassInfo =
{
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
(VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
DE_LENGTH_OF_ARRAY(attachmentsDescriptions), // deUint32 attachmentCount;
attachmentsDescriptions, // const VkAttachmentDescription* pAttachments;
1u, // deUint32 subpassCount;
&subpassDescription, // const VkSubpassDescription* pSubpasses;
0u, // deUint32 dependencyCount;
DE_NULL // const VkSubpassDependency* pDependencies;
};
return createRenderPass(vk, device, &renderPassInfo);
}
VkImageViewUsageCreateInfo makeImageViewUsageCreateInfo (const VkImageUsageFlags imageUsageFlags)
{
VkImageViewUsageCreateInfo imageViewUsageCreateInfo =
{
VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, //VkStructureType sType;
DE_NULL, //const void* pNext;
imageUsageFlags, //VkImageUsageFlags usage;
};
return imageViewUsageCreateInfo;
}
VkSamplerCreateInfo makeSamplerCreateInfo ()
{
const VkSamplerCreateInfo defaultSamplerParams =
{
VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
0u, // VkSamplerCreateFlags flags;
VK_FILTER_NEAREST, // VkFilter magFilter;
VK_FILTER_NEAREST, // VkFilter minFilter;
VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
0.0f, // float mipLodBias;
VK_FALSE, // VkBool32 anisotropyEnable;
1.0f, // float maxAnisotropy;
VK_FALSE, // VkBool32 compareEnable;
VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
0.0f, // float minLod;
0.25f, // float maxLod;
VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor;
VK_FALSE // VkBool32 unnormalizedCoordinates;
};
return defaultSamplerParams;
}
tcu::UVec3 getCompressedImageResolutionInBlocks (const vk::VkFormat format, const tcu::UVec3& size)
{
deUint32 blockWidth = getBlockWidth(format);
deUint32 blockHeight = getBlockHeight(format);
DE_ASSERT(size[2] == 1);
DE_ASSERT(blockWidth != 0 && blockHeight != 0);
deUint32 widthInBlocks = (size[0] + blockWidth - 1) / blockWidth;
deUint32 heightInBlocks = (size[1] + blockHeight - 1) / blockHeight;
return tcu::UVec3(widthInBlocks, heightInBlocks, 1);
}
tcu::UVec3 getCompressedImageResolutionBlockCeil (const vk::VkFormat format, const tcu::UVec3& size)
{
deUint32 blockWidth = getBlockWidth(format);
deUint32 blockHeight = getBlockHeight(format);
DE_ASSERT(size[2] == 1);
DE_ASSERT(blockWidth != 0 && blockHeight != 0);
deUint32 widthInBlocks = (size[0] + blockWidth - 1) / blockWidth;
deUint32 heightInBlocks = (size[1] + blockHeight - 1) / blockHeight;
return tcu::UVec3(blockWidth * widthInBlocks, blockHeight * heightInBlocks, 1);
}
VkDeviceSize getCompressedImageSizeInBytes (const vk::VkFormat format, const tcu::UVec3& size)
{
tcu::UVec3 sizeInBlocks = getCompressedImageResolutionInBlocks(format, size);
deUint32 blockBytes = getBlockSizeInBytes(format);
VkDeviceSize sizeBytes = sizeInBlocks[0] * sizeInBlocks[1] * sizeInBlocks[2] * blockBytes;
return sizeBytes;
}
VkDeviceSize getUncompressedImageSizeInBytes (const vk::VkFormat format, const tcu::UVec3& size)
{
const tcu::IVec3 sizeAsIVec3 = tcu::IVec3((int)size.x(), (int)size.y(), (int)size.z());
const VkDeviceSize sizeBytes = getImageSizeBytes(sizeAsIVec3, format);
return sizeBytes;
}
VkImageType mapImageType (const ImageType imageType)
{
switch (imageType)
{
case IMAGE_TYPE_1D:
case IMAGE_TYPE_1D_ARRAY:
case IMAGE_TYPE_BUFFER:
return VK_IMAGE_TYPE_1D;
case IMAGE_TYPE_2D:
case IMAGE_TYPE_2D_ARRAY:
case IMAGE_TYPE_CUBE:
case IMAGE_TYPE_CUBE_ARRAY:
return VK_IMAGE_TYPE_2D;
case IMAGE_TYPE_3D:
return VK_IMAGE_TYPE_3D;
default:
DE_ASSERT(false);
return VK_IMAGE_TYPE_LAST;
}
}
VkImageViewType mapImageViewType (const ImageType imageType)
{
switch (imageType)
{
case IMAGE_TYPE_1D: return VK_IMAGE_VIEW_TYPE_1D;
case IMAGE_TYPE_1D_ARRAY: return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
case IMAGE_TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D;
case IMAGE_TYPE_2D_ARRAY: return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
case IMAGE_TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D;
case IMAGE_TYPE_CUBE: return VK_IMAGE_VIEW_TYPE_CUBE;
case IMAGE_TYPE_CUBE_ARRAY: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
default:
DE_ASSERT(false);
return VK_IMAGE_VIEW_TYPE_LAST;
}
}
std::string getImageTypeName (const ImageType imageType)
{
switch (imageType)
{
case IMAGE_TYPE_1D: return "1d";
case IMAGE_TYPE_1D_ARRAY: return "1d_array";
case IMAGE_TYPE_2D: return "2d";
case IMAGE_TYPE_2D_ARRAY: return "2d_array";
case IMAGE_TYPE_3D: return "3d";
case IMAGE_TYPE_CUBE: return "cube";
case IMAGE_TYPE_CUBE_ARRAY: return "cube_array";
case IMAGE_TYPE_BUFFER: return "buffer";
default:
DE_ASSERT(false);
return "";
}
}
std::string getFormatPrefix (const tcu::TextureFormat& format)
{
return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" :
tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? "i" : "";
}
std::string getShaderImageType (const tcu::TextureFormat& format, const ImageType imageType, const bool multisample)
{
std::string formatPart = getFormatPrefix(format);
std::string imageTypePart;
if (multisample)
{
switch (imageType)
{
case IMAGE_TYPE_2D: imageTypePart = "2DMS"; break;
case IMAGE_TYPE_2D_ARRAY: imageTypePart = "2DMSArray"; break;
default:
DE_ASSERT(false);
}
}
else
{
switch (imageType)
{
case IMAGE_TYPE_1D: imageTypePart = "1D"; break;
case IMAGE_TYPE_1D_ARRAY: imageTypePart = "1DArray"; break;
case IMAGE_TYPE_2D: imageTypePart = "2D"; break;
case IMAGE_TYPE_2D_ARRAY: imageTypePart = "2DArray"; break;
case IMAGE_TYPE_3D: imageTypePart = "3D"; break;
case IMAGE_TYPE_CUBE: imageTypePart = "Cube"; break;
case IMAGE_TYPE_CUBE_ARRAY: imageTypePart = "CubeArray"; break;
case IMAGE_TYPE_BUFFER: imageTypePart = "Buffer"; break;
default:
DE_ASSERT(false);
}
}
return formatPart + "image" + imageTypePart;
}
std::string getShaderImageFormatQualifier (const tcu::TextureFormat& format)
{
if (!isPackedType(mapTextureFormat(format)))
{
const char* orderPart;
const char* typePart;
switch (format.order)
{
case tcu::TextureFormat::R: orderPart = "r"; break;
case tcu::TextureFormat::RG: orderPart = "rg"; break;
case tcu::TextureFormat::RGB: orderPart = "rgb"; break;
case tcu::TextureFormat::RGBA: orderPart = "rgba"; break;
case tcu::TextureFormat::sRGBA: orderPart = "rgba"; break;
default:
DE_FATAL("Order not found");
orderPart = DE_NULL;
}
switch (format.type)
{
case tcu::TextureFormat::FLOAT: typePart = "32f"; break;
case tcu::TextureFormat::HALF_FLOAT: typePart = "16f"; break;
case tcu::TextureFormat::UNSIGNED_INT32: typePart = "32ui"; break;
case tcu::TextureFormat::USCALED_INT16:
case tcu::TextureFormat::UNSIGNED_INT16: typePart = "16ui"; break;
case tcu::TextureFormat::USCALED_INT8:
case tcu::TextureFormat::UNSIGNED_INT8: typePart = "8ui"; break;
case tcu::TextureFormat::SIGNED_INT32: typePart = "32i"; break;
case tcu::TextureFormat::SSCALED_INT16:
case tcu::TextureFormat::SIGNED_INT16: typePart = "16i"; break;
case tcu::TextureFormat::SSCALED_INT8:
case tcu::TextureFormat::SIGNED_INT8: typePart = "8i"; break;
case tcu::TextureFormat::UNORM_INT16: typePart = "16"; break;
case tcu::TextureFormat::UNORM_INT8: typePart = "8"; break;
case tcu::TextureFormat::SNORM_INT16: typePart = "16_snorm"; break;
case tcu::TextureFormat::SNORM_INT8: typePart = "8_snorm"; break;
default:
DE_FATAL("Type not found");
typePart = DE_NULL;
}
return std::string() + orderPart + typePart;
}
else
{
switch (mapTextureFormat(format))
{
case VK_FORMAT_B10G11R11_UFLOAT_PACK32: return "r11f_g11f_b10f";
case VK_FORMAT_A2B10G10R10_UNORM_PACK32: return "rgb10_a2";
case VK_FORMAT_A2B10G10R10_UINT_PACK32: return "rgb10_a2ui";
default:
DE_FATAL("Qualifier not found");
return "";
}
}
}
std::string getGlslSamplerType (const tcu::TextureFormat& format, VkImageViewType type)
{
const char* typePart = DE_NULL;
const char* formatPart = tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" :
tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? "i" : "";
switch (type)
{
case VK_IMAGE_VIEW_TYPE_1D: typePart = "sampler1D"; break;
case VK_IMAGE_VIEW_TYPE_1D_ARRAY: typePart = "sampler1DArray"; break;
case VK_IMAGE_VIEW_TYPE_2D: typePart = "sampler2D"; break;
case VK_IMAGE_VIEW_TYPE_2D_ARRAY: typePart = "sampler2DArray"; break;
case VK_IMAGE_VIEW_TYPE_3D: typePart = "sampler3D"; break;
case VK_IMAGE_VIEW_TYPE_CUBE: typePart = "samplerCube"; break;
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: typePart = "samplerCubeArray"; break;
default:
DE_FATAL("Unknown image view type");
break;
}
return std::string(formatPart) + typePart;
}
const char* getGlslInputFormatType (const vk::VkFormat format)
{
switch (format)
{
// 64-bit
case VK_FORMAT_R16G16B16A16_UNORM: return "subpassInput";
case VK_FORMAT_R16G16B16A16_SNORM: return "subpassInput";
case VK_FORMAT_R16G16B16A16_USCALED: return "subpassInput";
case VK_FORMAT_R16G16B16A16_SSCALED: return "subpassInput";
case VK_FORMAT_R16G16B16A16_UINT: return "usubpassInput";
case VK_FORMAT_R16G16B16A16_SINT: return "isubpassInput";
case VK_FORMAT_R16G16B16A16_SFLOAT: return "subpassInput";
case VK_FORMAT_R32G32_UINT: return "usubpassInput";
case VK_FORMAT_R32G32_SINT: return "isubpassInput";
case VK_FORMAT_R32G32_SFLOAT: return "subpassInput";
// TODO: case VK_FORMAT_R64_UINT: return "usubpassInput";
// TODO: case VK_FORMAT_R64_SINT: return "isubpassInput";
// TODO: case VK_FORMAT_R64_SFLOAT: return "subpassInput";
// 128-bit
case VK_FORMAT_R32G32B32A32_UINT: return "usubpassInput";
case VK_FORMAT_R32G32B32A32_SINT: return "isubpassInput";
case VK_FORMAT_R32G32B32A32_SFLOAT: return "subpassInput";
// TODO: case VK_FORMAT_R64G64_UINT: return "usubpassInput";
// TODO: case VK_FORMAT_R64G64_SINT: return "isubpassInput";
// TODO: case VK_FORMAT_R64G64_SFLOAT: return "subpassInput";
default: TCU_THROW(InternalError, "Unknown format");
}
}
const char* getGlslFormatType (const vk::VkFormat format)
{
switch (format)
{
// 64-bit
case VK_FORMAT_R16G16B16A16_UNORM: return "vec4";
case VK_FORMAT_R16G16B16A16_SNORM: return "vec4";
case VK_FORMAT_R16G16B16A16_USCALED: return "vec4";
case VK_FORMAT_R16G16B16A16_SSCALED: return "vec4";
case VK_FORMAT_R16G16B16A16_UINT: return "uvec4";
case VK_FORMAT_R16G16B16A16_SINT: return "ivec4";
case VK_FORMAT_R16G16B16A16_SFLOAT: return "vec4";
case VK_FORMAT_R32G32_UINT: return "uvec2";
case VK_FORMAT_R32G32_SINT: return "ivec2";
case VK_FORMAT_R32G32_SFLOAT: return "vec2";
// TODO: case VK_FORMAT_R64_UINT: return "uint64";
// TODO: case VK_FORMAT_R64_SINT: return "int64";
// TODO: case VK_FORMAT_R64_SFLOAT: return "double";
// 128-bit
case VK_FORMAT_R32G32B32A32_UINT: return "uvec4";
case VK_FORMAT_R32G32B32A32_SINT: return "ivec4";
case VK_FORMAT_R32G32B32A32_SFLOAT: return "vec4";
// TODO: case VK_FORMAT_R64G64_UINT: return "ulvec2";
// TODO: case VK_FORMAT_R64G64_SINT: return "ilvec2";
// TODO: case VK_FORMAT_R64G64_SFLOAT: return "dvec2";
default: TCU_THROW(InternalError, "Unknown format");
}
}
const char* getGlslAttachmentType (const vk::VkFormat format)
{
const tcu::TextureFormat textureFormat = mapVkFormat(format);
const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(textureFormat.type);
switch (channelClass)
{
case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
return "ivec4";
case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
return "uvec4";
case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
return "vec4";
default:
DE_FATAL("Unknown channel class");
return "";
}
}
const char* getGlslInputAttachmentType (const vk::VkFormat format)
{
const tcu::TextureFormat textureFormat = mapVkFormat(format);
const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(textureFormat.type);
switch (channelClass)
{
case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
return "isubpassInput";
case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
return "usubpassInput";
case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
return "subpassInput";
default:
DE_FATAL("Unknown channel class");
return "";
}
}
bool isPackedType (const vk::VkFormat format)
{
const tcu::TextureFormat textureFormat = mapVkFormat(format);
DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELTYPE_LAST == 48);
switch (textureFormat.type)
{
case tcu::TextureFormat::UNORM_BYTE_44:
case tcu::TextureFormat::UNORM_SHORT_565:
case tcu::TextureFormat::UNORM_SHORT_555:
case tcu::TextureFormat::UNORM_SHORT_4444:
case tcu::TextureFormat::UNORM_SHORT_5551:
case tcu::TextureFormat::UNORM_SHORT_1555:
case tcu::TextureFormat::UNORM_INT_101010:
case tcu::TextureFormat::SNORM_INT_1010102_REV:
case tcu::TextureFormat::UNORM_INT_1010102_REV:
case tcu::TextureFormat::UNSIGNED_BYTE_44:
case tcu::TextureFormat::UNSIGNED_SHORT_565:
case tcu::TextureFormat::UNSIGNED_SHORT_4444:
case tcu::TextureFormat::UNSIGNED_SHORT_5551:
case tcu::TextureFormat::SIGNED_INT_1010102_REV:
case tcu::TextureFormat::UNSIGNED_INT_1010102_REV:
case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV:
case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
case tcu::TextureFormat::UNSIGNED_INT_24_8:
case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
case tcu::TextureFormat::SSCALED_INT_1010102_REV:
case tcu::TextureFormat::USCALED_INT_1010102_REV:
return true;
default:
return false;
}
}
bool isComponentSwizzled (const vk::VkFormat format)
{
const tcu::TextureFormat textureFormat = mapVkFormat(format);
DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
switch (textureFormat.order)
{
case tcu::TextureFormat::ARGB:
case tcu::TextureFormat::BGR:
case tcu::TextureFormat::BGRA:
case tcu::TextureFormat::sBGR:
case tcu::TextureFormat::sBGRA:
return true;
default:
return false;
}
}
int getNumUsedChannels (const vk::VkFormat format)
{
// make sure this function will be checked if type table is updated
DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
const tcu::TextureFormat textureFormat = mapVkFormat(format);
return getNumUsedChannels(textureFormat.order);
}
bool isFormatImageLoadStoreCapable (const vk::VkFormat format)
{
// These come from https://www.khronos.org/registry/vulkan/specs/1.1/html/vkspec.html#spirvenv-image-formats
switch (format)
{
case VK_FORMAT_R32G32B32A32_SFLOAT:
case VK_FORMAT_R16G16B16A16_SFLOAT:
case VK_FORMAT_R32_SFLOAT:
case VK_FORMAT_R8G8B8A8_UNORM:
case VK_FORMAT_R8G8B8A8_SNORM:
case VK_FORMAT_R32G32_SFLOAT:
case VK_FORMAT_R16G16_SFLOAT:
case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
case VK_FORMAT_R16_SFLOAT:
case VK_FORMAT_R16G16B16A16_UNORM:
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
case VK_FORMAT_R16G16_UNORM:
case VK_FORMAT_R8G8_UNORM:
case VK_FORMAT_R16_UNORM:
case VK_FORMAT_R8_UNORM:
case VK_FORMAT_R16G16B16A16_SNORM:
case VK_FORMAT_R16G16_SNORM:
case VK_FORMAT_R8G8_SNORM:
case VK_FORMAT_R16_SNORM:
case VK_FORMAT_R8_SNORM:
case VK_FORMAT_R32G32B32A32_SINT:
case VK_FORMAT_R16G16B16A16_SINT:
case VK_FORMAT_R8G8B8A8_SINT:
case VK_FORMAT_R32_SINT:
case VK_FORMAT_R32G32_SINT:
case VK_FORMAT_R16G16_SINT:
case VK_FORMAT_R8G8_SINT:
case VK_FORMAT_R16_SINT:
case VK_FORMAT_R8_SINT:
case VK_FORMAT_R32G32B32A32_UINT:
case VK_FORMAT_R16G16B16A16_UINT:
case VK_FORMAT_R8G8B8A8_UINT:
case VK_FORMAT_R32_UINT:
case VK_FORMAT_A2B10G10R10_UINT_PACK32:
case VK_FORMAT_R32G32_UINT:
case VK_FORMAT_R16G16_UINT:
case VK_FORMAT_R8G8_UINT:
case VK_FORMAT_R16_UINT:
case VK_FORMAT_R8_UINT:
return true;
default:
return false;
}
}
std::string getFormatShortString (const VkFormat format)
{
const std::string fullName = getFormatName(format);
DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
return de::toLower(fullName.substr(10));
}
std::vector<tcu::Vec4> createFullscreenQuad (void)
{
const tcu::Vec4 lowerLeftVertex (-1.0f, -1.0f, 0.0f, 1.0f);
const tcu::Vec4 upperLeftVertex (-1.0f, 1.0f, 0.0f, 1.0f);
const tcu::Vec4 lowerRightVertex (1.0f, -1.0f, 0.0f, 1.0f);
const tcu::Vec4 upperRightVertex (1.0f, 1.0f, 0.0f, 1.0f);
const tcu::Vec4 vertices[6] =
{
lowerLeftVertex,
lowerRightVertex,
upperLeftVertex,
upperLeftVertex,
lowerRightVertex,
upperRightVertex
};
return std::vector<tcu::Vec4>(vertices, vertices + DE_LENGTH_OF_ARRAY(vertices));
}
vk::VkBufferImageCopy makeBufferImageCopy (const deUint32 imageWidth, const deUint32 imageHeight, const deUint32 mipLevel, const deUint32 layer)
{
const VkBufferImageCopy copyParams =
{
(VkDeviceSize)0u, // bufferOffset
imageWidth, // bufferRowLength
imageHeight, // bufferImageHeight
{
VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
mipLevel, // mipLevel
layer, // baseArrayLayer
1u, // layerCount
}, // imageSubresource
{ 0u, 0u, 0u }, // imageOffset
{
imageWidth,
imageHeight,
1u
} // imageExtent
};
return copyParams;
}
vk::VkBufferImageCopy makeBufferImageCopy (const deUint32 imageWidth, const deUint32 imageHeight, const deUint32 mipLevel, const deUint32 layer, const deUint32 bufferRowLength, const deUint32 bufferImageHeight)
{
const VkBufferImageCopy copyParams =
{
(VkDeviceSize)0u, // bufferOffset
bufferRowLength, // bufferRowLength
bufferImageHeight, // bufferImageHeight
{
VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
mipLevel, // mipLevel
layer, // baseArrayLayer
1u, // layerCount
}, // imageSubresource
{ 0u, 0u, 0u }, // imageOffset
{
imageWidth,
imageHeight,
1u
} // imageExtent
};
return copyParams;
}
void beginRenderPass (const DeviceInterface& vk,
const VkCommandBuffer commandBuffer,
const VkRenderPass renderPass,
const VkFramebuffer framebuffer,
const VkExtent2D& renderSize)
{
const VkRect2D renderArea =
{
{0, 0}, // VkOffset2D offset;
renderSize, // VkExtent2D extent;
};
beginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea, tcu::Vec4(0.0f), 0.0f, 0u);
}
} // image
} // vkt