blob: fac4db367a49d9728cdf225fcead61c5a61891dd [file] [log] [blame]
/*------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2019 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 vktImageAstcDecodeModeTests.cpp
* \brief Astc decode mode tests
*//*--------------------------------------------------------------------*/
#include "vktImageAstcDecodeModeTests.hpp"
#include "vktImageLoadStoreUtil.hpp"
#include "vktTestCaseUtil.hpp"
#include "vkBarrierUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuTexture.hpp"
#include "tcuCompressedTexture.hpp"
#include "tcuImageCompare.hpp"
#include "deRandom.hpp"
#include <vector>
using namespace vk;
namespace vkt
{
namespace image
{
namespace
{
using std::string;
using std::vector;
using tcu::TestContext;
using tcu::TestStatus;
using tcu::UVec3;
using tcu::IVec3;
using tcu::CompressedTexFormat;
using tcu::CompressedTexture;
using de::MovePtr;
using de::SharedPtr;
using de::Random;
struct TestParameters
{
ImageType imageType;
UVec3 imageSize;
VkFormat testedFormat;
deBool testedIsUnorm;
VkFormat testedDecodeMode;
VkImageUsageFlags testedImageUsage;
VkFormat resultFormat;
VkImageUsageFlags resultImageUsage;
};
class BasicComputeTestInstance : public TestInstance
{
public:
BasicComputeTestInstance (Context& context,
const TestParameters& parameters);
TestStatus iterate (void);
protected:
void generateData (deUint8* toFill,
const size_t size,
const VkFormat format,
const deUint32 layer,
const deUint32 level);
protected:
const TestParameters m_parameters;
};
BasicComputeTestInstance::BasicComputeTestInstance (Context& context, const TestParameters& parameters)
: TestInstance (context)
, m_parameters (parameters)
{
}
TestStatus BasicComputeTestInstance::iterate (void)
{
Allocator& allocator = m_context.getDefaultAllocator();
const DeviceInterface& vk = m_context.getDeviceInterface();
const VkDevice device = m_context.getDevice();
const VkQueue queue = m_context.getUniversalQueue();
const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
const VkImageType imageType = mapImageType(m_parameters.imageType);
const VkExtent3D extentCompressed = makeExtent3D(getCompressedImageResolutionInBlocks(m_parameters.testedFormat, m_parameters.imageSize));
const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
const Unique<VkShaderModule> shaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0));
const VkImageCreateInfo compressedImageInfo =
{
VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT |
VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, // VkImageCreateFlags flags;
imageType, // VkImageType imageType;
m_parameters.testedFormat, // VkFormat format;
extentCompressed, // VkExtent3D extent;
1u, // deUint32 mipLevels;
1u, // deUint32 arrayLayers;
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
VK_IMAGE_USAGE_SAMPLED_BIT |
VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
0u, // deUint32 queueFamilyIndexCount;
DE_NULL, // const deUint32* pQueueFamilyIndices;
VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
};
const VkImageCreateInfo resultImageInfo =
{
VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
0u, // VkImageCreateFlags flags;
imageType, // VkImageType imageType;
m_parameters.resultFormat, // VkFormat format;
extentCompressed, // VkExtent3D extent;
1u, // deUint32 mipLevels;
1u, // deUint32 arrayLayers;
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
VK_IMAGE_USAGE_SAMPLED_BIT |
VK_IMAGE_USAGE_STORAGE_BIT |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
0u, // deUint32 queueFamilyIndexCount;
DE_NULL, // const deUint32* pQueueFamilyIndices;
VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
};
// create images
Image testedImage (vk, device, allocator, compressedImageInfo, MemoryRequirement::Any);
Image referenceImage (vk, device, allocator, compressedImageInfo, MemoryRequirement::Any);
Image resultImage (vk, device, allocator, resultImageInfo, MemoryRequirement::Any);
// create image views
const VkImageViewType imageViewType (mapImageViewType(m_parameters.imageType));
VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
VkFormat viewFormat = m_parameters.testedIsUnorm ? VK_FORMAT_R32G32B32A32_UINT : VK_FORMAT_R32G32B32A32_SINT;
VkImageViewASTCDecodeModeEXT decodeMode =
{
VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT,
DE_NULL,
m_parameters.testedDecodeMode
};
const VkImageViewCreateInfo imageViewParams =
{
VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
&decodeMode, // const void* pNext;
0u, // VkImageViewCreateFlags flags;
testedImage.get(), // VkImage image;
imageViewType, // VkImageViewType viewType;
viewFormat, // VkFormat format;
makeComponentMappingRGBA(), // VkComponentMapping components;
subresourceRange, // VkImageSubresourceRange subresourceRange;
};
Move<VkImageView> testedView = createImageView(vk, device, &imageViewParams);
Move<VkImageView> referenceView = makeImageView(vk, device, referenceImage.get(), imageViewType, viewFormat, subresourceRange);
Move<VkImageView> resultView = makeImageView(vk, device, resultImage.get(), imageViewType, m_parameters.resultFormat,
makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, resultImageInfo.extent.depth, 0u, resultImageInfo.arrayLayers));
Move<VkDescriptorSetLayout> descriptorSetLayout = DescriptorSetLayoutBuilder()
.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT)
.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT)
.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
.build(vk, device);
Move<VkDescriptorPool> descriptorPool = DescriptorPoolBuilder()
.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, compressedImageInfo.arrayLayers)
.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, compressedImageInfo.arrayLayers)
.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, resultImageInfo.arrayLayers)
.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, resultImageInfo.arrayLayers);
Move<VkDescriptorSet> descriptorSet = makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout));
const Unique<VkPipeline> pipeline (makeComputePipeline(vk, device, *pipelineLayout, *shaderModule));
const VkDeviceSize bufferSizeCompresed = getCompressedImageSizeInBytes(m_parameters.testedFormat, m_parameters.imageSize);
const VkDeviceSize bufferSizeUncompressed = getImageSizeBytes(IVec3((int)extentCompressed.width, (int)extentCompressed.height, (int)extentCompressed.depth), m_parameters.resultFormat);
VkBufferCreateInfo compressedBufferCI = makeBufferCreateInfo(bufferSizeCompresed, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
VkBufferCreateInfo uncompressedBufferCI = makeBufferCreateInfo(bufferSizeUncompressed, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
Buffer inBuffer (vk, device, allocator, compressedBufferCI, MemoryRequirement::HostVisible);
Buffer resultBuffer (vk, device, allocator, uncompressedBufferCI, MemoryRequirement::HostVisible);
Move<VkSampler> sampler;
// generate data for compressed image and copy it to in buffer
{
vector<deUint8> generatedData;
generatedData.resize(static_cast<size_t>(bufferSizeCompresed));
generateData(generatedData.data(), generatedData.size(), m_parameters.testedFormat, 0u, 0u);
const Allocation& alloc = inBuffer.getAllocation();
deMemcpy(alloc.getHostPtr(), generatedData.data(), generatedData.size());
flushAlloc(vk, device, alloc);
}
{
const VkSamplerCreateInfo createInfo =
{
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_EQUAL, //VkCompareOp compareOp;
0.0f, //float minLod;
1.0f, //float maxLod;
VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, //VkBorderColor borderColor;
VK_FALSE, //VkBool32 unnormalizedCoordinates;
};
sampler = createSampler(vk, device, &createInfo);
}
VkDescriptorImageInfo descriptorImageInfos[] =
{
makeDescriptorImageInfo(*sampler, *testedView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
makeDescriptorImageInfo(*sampler, *referenceView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
makeDescriptorImageInfo(DE_NULL, *resultView, VK_IMAGE_LAYOUT_GENERAL),
};
DescriptorSetUpdateBuilder()
.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfos[0])
.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfos[1])
.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfos[2])
.update(vk, device);
beginCommandBuffer(vk, *cmdBuffer);
{
// copy input buffer to tested and reference images
{
Image* inImages[] = { &testedImage, &referenceImage };
for (Image* image : inImages)
{
const VkImageMemoryBarrier preCopyImageBarrier = makeImageMemoryBarrier(
0u, VK_ACCESS_TRANSFER_WRITE_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
image->get(), subresourceRange);
const VkBufferMemoryBarrier flushHostCopyBarrier = makeBufferMemoryBarrier(
VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
inBuffer.get(), 0ull, bufferSizeCompresed);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
(VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 1u, &flushHostCopyBarrier, 1u, &preCopyImageBarrier);
const VkBufferImageCopy copyRegion =
{
0ull, //VkDeviceSize bufferOffset;
0u, //deUint32 bufferRowLength;
0u, //deUint32 bufferImageHeight;
makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u), //VkImageSubresourceLayers imageSubresource;
makeOffset3D(0, 0, 0), //VkOffset3D imageOffset;
extentCompressed, //VkExtent3D imageExtent;
};
vk.cmdCopyBufferToImage(*cmdBuffer, inBuffer.get(), image->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
}
}
// bind pipeline and descriptors
vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
{
const VkImageMemoryBarrier preShaderImageBarriers[] =
{
makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
testedImage.get(), subresourceRange),
makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
referenceImage.get(), subresourceRange),
makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_WRITE_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
resultImage.get(), subresourceRange)
};
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
(VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, (const VkBufferMemoryBarrier*)DE_NULL,
DE_LENGTH_OF_ARRAY(preShaderImageBarriers), preShaderImageBarriers);
}
vk.cmdDispatch(*cmdBuffer, extentCompressed.width, extentCompressed.height, extentCompressed.depth);
{
const VkImageMemoryBarrier postShaderImageBarriers[] =
{
makeImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
resultImage.get(), subresourceRange)
};
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
(VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 0u, (const VkBufferMemoryBarrier*)DE_NULL,
DE_LENGTH_OF_ARRAY(postShaderImageBarriers), postShaderImageBarriers);
}
const VkBufferImageCopy copyRegion =
{
0ull, // VkDeviceSize bufferOffset;
0u, // deUint32 bufferRowLength;
0u, // deUint32 bufferImageHeight;
makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u), // VkImageSubresourceLayers imageSubresource;
makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
resultImageInfo.extent, // VkExtent3D imageExtent;
};
vk.cmdCopyImageToBuffer(*cmdBuffer, resultImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, resultBuffer.get(), 1u, &copyRegion);
{
const VkBufferMemoryBarrier postCopyBufferBarrier[] =
{
makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
resultBuffer.get(), 0ull, bufferSizeUncompressed),
};
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
(VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(postCopyBufferBarrier), postCopyBufferBarrier,
0u, (const VkImageMemoryBarrier*)DE_NULL);
}
}
endCommandBuffer(vk, *cmdBuffer);
submitCommandsAndWait(vk, device, queue, *cmdBuffer);
const Allocation& resultAlloc = resultBuffer.getAllocation();
invalidateAlloc(vk, device, resultAlloc);
// verification is done in shader - here we just check if one of pixels has wrong value
const size_t numBytes = static_cast<size_t>(bufferSizeUncompressed);
deUint8* result = static_cast<deUint8*>(resultAlloc.getHostPtr());
for (size_t i = 0 ; i < numBytes ; i += 4)
{
// expected result should be around 128 (if reference is same as tested mode then we return 0.5)
if ((result[i] < 100) || (result[i] > 150))
return TestStatus::fail("Fail");
}
return TestStatus::pass("Pass");
}
void BasicComputeTestInstance::generateData (deUint8* toFill,
const size_t size,
const VkFormat format,
const deUint32 layer,
const deUint32 level)
{
// Random data
deUint32* start32 = reinterpret_cast<deUint32*>(toFill);
size_t sizeToRnd32 = size / sizeof(deUint32);
deUint32 seed = (layer << 24) ^ (level << 16) ^ static_cast<deUint32>(format);
Random rnd (seed);
for (size_t i = 0; i < sizeToRnd32; i++)
start32[i] = rnd.getUint32();
}
class AstcDecodeModeCase : public TestCase
{
public:
AstcDecodeModeCase (TestContext& testCtx,
const std::string& name,
const std::string& desc,
const TestParameters& parameters);
virtual void checkSupport (Context& context) const;
void initPrograms (SourceCollections& programCollection) const;
TestInstance* createInstance (Context& context) const;
protected:
const TestParameters m_parameters;
};
AstcDecodeModeCase::AstcDecodeModeCase (TestContext& testCtx,
const std::string& name,
const std::string& desc,
const TestParameters& parameters)
: TestCase (testCtx, name, desc)
, m_parameters (parameters)
{
}
void AstcDecodeModeCase::checkSupport (Context& context) const
{
const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
const InstanceInterface& vk = context.getInstanceInterface();
context.requireDeviceFunctionality("VK_EXT_astc_decode_mode");
if (!getPhysicalDeviceFeatures(vk, physicalDevice).textureCompressionASTC_LDR)
TCU_THROW(NotSupportedError, "textureCompressionASTC_LDR not supported");
VkImageFormatProperties imageFormatProperties;
if (VK_ERROR_FORMAT_NOT_SUPPORTED == vk.getPhysicalDeviceImageFormatProperties(physicalDevice, m_parameters.testedFormat,
mapImageType(m_parameters.imageType), VK_IMAGE_TILING_OPTIMAL,
m_parameters.testedImageUsage, 0u, &imageFormatProperties))
TCU_THROW(NotSupportedError, "Operation not supported with this image format");
if (VK_ERROR_FORMAT_NOT_SUPPORTED == vk.getPhysicalDeviceImageFormatProperties(physicalDevice, m_parameters.resultFormat,
mapImageType(m_parameters.imageType), VK_IMAGE_TILING_OPTIMAL,
m_parameters.resultImageUsage, 0u, &imageFormatProperties))
TCU_THROW(NotSupportedError, "Operation not supported with this image format");
if ((m_parameters.testedDecodeMode == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) &&
!context.getASTCDecodeFeaturesEXT().decodeModeSharedExponent)
TCU_THROW(NotSupportedError, "decodeModeSharedExponent not supported");
VkFormatProperties properties;
context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_parameters.resultFormat, &properties);
if (!(properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
TCU_THROW(NotSupportedError, "Format storage feature not supported");
}
void AstcDecodeModeCase::initPrograms (vk::SourceCollections& programCollection) const
{
DE_ASSERT(m_parameters.imageSize.x() > 0);
DE_ASSERT(m_parameters.imageSize.y() > 0);
VkFormat compatibileFormat = m_parameters.testedIsUnorm ? VK_FORMAT_R32G32B32A32_UINT : VK_FORMAT_R32G32B32A32_SINT;
tcu::TextureFormat testedTextureFormat = mapVkFormat(compatibileFormat);
VkImageViewType imageViewType = mapImageViewType(m_parameters.imageType);
string samplerType = getGlslSamplerType(testedTextureFormat, imageViewType);
const string formatQualifierStr = getShaderImageFormatQualifier(mapVkFormat(m_parameters.resultFormat));
const string imageTypeStr = getShaderImageType(mapVkFormat(m_parameters.resultFormat), m_parameters.imageType);
std::ostringstream src;
src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
<< "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\n"
<< "layout (binding = 0) uniform " << samplerType << " compressed_tested;\n"
<< "layout (binding = 1) uniform " << samplerType << " compressed_reference;\n"
<< "layout (binding = 2, " << formatQualifierStr << ") writeonly uniform " << imageTypeStr << " result;\n"
<< "void main (void)\n"
<< "{\n"
<< " const vec2 pixels_resolution = vec2(gl_NumWorkGroups.xy);\n"
<< " const vec2 cord = vec2(gl_GlobalInvocationID.xy) / vec2(pixels_resolution);\n"
<< " const ivec2 pos = ivec2(gl_GlobalInvocationID.xy); \n"
<< " vec4 tested = texture(compressed_tested, cord);\n"
<< " vec4 reference = texture(compressed_reference, cord);\n";
// special case for e5b9g9r9 decode mode that was set on unorm astc formats
// here negative values are clamped to zero and alpha is set to 1
if (m_parameters.testedIsUnorm && (m_parameters.testedDecodeMode == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32))
src << " reference = max(vec4(0,0,0,1), reference);\n"
" float result_color = 0.5 * float(distance(tested, reference) < 0.01);\n";
else
src << " float result_color = 0.5 * float(distance(tested, reference) < 0.01);\n";
src << " imageStore(result, pos, vec4(result_color));\n"
<< "}\n";
programCollection.glslSources.add("comp") << glu::ComputeSource(src.str());
}
TestInstance* AstcDecodeModeCase::createInstance (Context& context) const
{
return new BasicComputeTestInstance(context, m_parameters);
}
} // anonymous ns
tcu::TestCaseGroup* createImageAstcDecodeModeTests (tcu::TestContext& testCtx)
{
struct FormatData
{
VkFormat format;
std::string name;
deBool isUnorm;
};
const FormatData astcFormats[] =
{
{ VK_FORMAT_ASTC_4x4_UNORM_BLOCK, "4x4_unorm", DE_TRUE },
{ VK_FORMAT_ASTC_4x4_SRGB_BLOCK, "4x4_srgb", DE_FALSE },
{ VK_FORMAT_ASTC_5x4_UNORM_BLOCK, "5x4_unorm", DE_TRUE },
{ VK_FORMAT_ASTC_5x4_SRGB_BLOCK, "5x4_srgb", DE_FALSE },
{ VK_FORMAT_ASTC_5x5_UNORM_BLOCK, "5x5_unorm", DE_TRUE },
{ VK_FORMAT_ASTC_5x5_SRGB_BLOCK, "5x5_srgb", DE_FALSE },
{ VK_FORMAT_ASTC_6x5_UNORM_BLOCK, "6x5_unorm", DE_TRUE },
{ VK_FORMAT_ASTC_6x5_SRGB_BLOCK, "6x5_srgb", DE_FALSE },
{ VK_FORMAT_ASTC_6x6_UNORM_BLOCK, "6x6_unorm", DE_TRUE },
{ VK_FORMAT_ASTC_6x6_SRGB_BLOCK, "6x6_srgb", DE_FALSE },
{ VK_FORMAT_ASTC_8x5_UNORM_BLOCK, "8x5_unorm", DE_TRUE },
{ VK_FORMAT_ASTC_8x5_SRGB_BLOCK, "8x5_srgb", DE_FALSE },
{ VK_FORMAT_ASTC_8x6_UNORM_BLOCK, "8x6_unorm", DE_TRUE },
{ VK_FORMAT_ASTC_8x6_SRGB_BLOCK, "8x6_srgb", DE_FALSE },
{ VK_FORMAT_ASTC_8x8_UNORM_BLOCK, "8x8_unorm", DE_TRUE },
{ VK_FORMAT_ASTC_8x8_SRGB_BLOCK, "8x8_srgb", DE_FALSE },
{ VK_FORMAT_ASTC_10x5_UNORM_BLOCK, "10x5_unorm", DE_TRUE },
{ VK_FORMAT_ASTC_10x5_SRGB_BLOCK, "10x5_srgb", DE_FALSE },
{ VK_FORMAT_ASTC_10x6_UNORM_BLOCK, "10x6_unorm", DE_TRUE },
{ VK_FORMAT_ASTC_10x6_SRGB_BLOCK, "10x6_srgb", DE_FALSE },
{ VK_FORMAT_ASTC_10x8_UNORM_BLOCK, "10x8_unorm", DE_TRUE },
{ VK_FORMAT_ASTC_10x8_SRGB_BLOCK, "10x8_srgb", DE_FALSE },
{ VK_FORMAT_ASTC_10x10_UNORM_BLOCK, "10x10_unorm", DE_TRUE },
{ VK_FORMAT_ASTC_10x10_SRGB_BLOCK, "10x10_srgb", DE_FALSE },
{ VK_FORMAT_ASTC_12x10_UNORM_BLOCK, "12x10_unorm", DE_TRUE },
{ VK_FORMAT_ASTC_12x10_SRGB_BLOCK, "12x10_srgb", DE_FALSE },
{ VK_FORMAT_ASTC_12x12_UNORM_BLOCK, "12x12_unorm", DE_TRUE },
{ VK_FORMAT_ASTC_12x12_SRGB_BLOCK, "12x12_srgb", DE_FALSE },
};
struct DecodeModeData
{
VkFormat mode;
std::string name;
};
const DecodeModeData decodeModes[] =
{
{ VK_FORMAT_R16G16B16A16_SFLOAT, "r16g16b16a16_sfloat" },
{ VK_FORMAT_R8G8B8A8_UNORM, "r8g8b8a8_unorm" },
{ VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, "e5b9g9r9_ufloat_pack32" }
};
MovePtr<tcu::TestCaseGroup> astcDecodeModeTests(new tcu::TestCaseGroup(testCtx, "astc_decode_mode", "Intermediate decoding precision cases"));
for (const FormatData& format : astcFormats)
{
for (const DecodeModeData& mode : decodeModes)
{
const TestParameters parameters =
{
IMAGE_TYPE_2D,
UVec3(64u, 64u, 1u),
format.format,
format.isUnorm,
mode.mode,
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
VK_FORMAT_R8G8B8A8_UNORM,
VK_IMAGE_USAGE_STORAGE_BIT
};
std::string name = format.name + "_to_" + mode.name;
astcDecodeModeTests->addChild(new AstcDecodeModeCase(testCtx, name, "", parameters));
}
}
return astcDecodeModeTests.release();
}
} // image
} // vkt