From 387999c58e55306e26ea6a8abd371174d35ee640 Mon Sep 17 00:00:00 2001 From: Pyry Haulos Date: Wed, 21 Sep 2016 18:26:31 -0700 Subject: [PATCH] Use tex lookup verifier in ImageSamplingInstance Simple image comparison is ill-equipped to handle all possible precision and behavior differences (cube map corner filtering for example). This change replaces old image comparison method with use of texture lookup verification utilities. Instead of rendering a reference image, texture coordinates generated by the reference rasterizer are captured. The captured coordinates are then used to verify the result color values retured by the implementation using the texture lookup verification code. This affects: * dEQP-VK.pipeline.image.* * dEQP-VK.pipeline.sampler.* * dEQP-VK.pipeline.image_view.* Fixes #297 Fixes #340 Change-Id: I856000bd4d4aa7ab6c1e69af09f3655b63018b93 --- .../vulkancts/framework/vulkan/vkImageUtil.cpp | 31 - .../vulkancts/framework/vulkan/vkImageUtil.hpp | 2 - .../pipeline/vktPipelineImageSamplingInstance.cpp | 859 +++++++++++++++------ .../vulkan/pipeline/vktPipelineImageTests.cpp | 12 +- .../vulkan/pipeline/vktPipelineImageUtil.cpp | 36 + .../vulkan/pipeline/vktPipelineImageUtil.hpp | 4 + .../vulkan/pipeline/vktPipelineImageViewTests.cpp | 16 +- .../pipeline/vktPipelineReferenceRenderer.hpp | 86 +-- .../vulkan/pipeline/vktPipelineSamplerTests.cpp | 11 +- 9 files changed, 674 insertions(+), 383 deletions(-) diff --git a/external/vulkancts/framework/vulkan/vkImageUtil.cpp b/external/vulkancts/framework/vulkan/vkImageUtil.cpp index f529ee7..8be42c8 100644 --- a/external/vulkancts/framework/vulkan/vkImageUtil.cpp +++ b/external/vulkancts/framework/vulkan/vkImageUtil.cpp @@ -874,37 +874,6 @@ tcu::Sampler::FilterMode mapVkMagTexFilter (VkFilter filter) return tcu::Sampler::FILTERMODE_LAST; } - -int mapVkComponentSwizzle (const vk::VkComponentSwizzle& channelSwizzle) -{ - switch (channelSwizzle) - { - case vk::VK_COMPONENT_SWIZZLE_ZERO: return 0; - case vk::VK_COMPONENT_SWIZZLE_ONE: return 1; - case vk::VK_COMPONENT_SWIZZLE_R: return 2; - case vk::VK_COMPONENT_SWIZZLE_G: return 3; - case vk::VK_COMPONENT_SWIZZLE_B: return 4; - case vk::VK_COMPONENT_SWIZZLE_A: return 5; - default: - break; - } - - DE_ASSERT(false); - return 0; -} - -tcu::UVec4 mapVkComponentMapping (const vk::VkComponentMapping& mapping) -{ - tcu::UVec4 swizzle; - - swizzle.x() = mapVkComponentSwizzle(mapping.r); - swizzle.y() = mapVkComponentSwizzle(mapping.g); - swizzle.z() = mapVkComponentSwizzle(mapping.b); - swizzle.w() = mapVkComponentSwizzle(mapping.a); - - return swizzle; -} - //! Get a format the matches the layout in buffer memory used for a //! buffer<->image copy on a depth/stencil format. tcu::TextureFormat getDepthCopyFormat (VkFormat combinedFormat) diff --git a/external/vulkancts/framework/vulkan/vkImageUtil.hpp b/external/vulkancts/framework/vulkan/vkImageUtil.hpp index 0c16a05..06f6e09 100644 --- a/external/vulkancts/framework/vulkan/vkImageUtil.hpp +++ b/external/vulkancts/framework/vulkan/vkImageUtil.hpp @@ -50,8 +50,6 @@ tcu::Sampler::CompareMode mapVkSamplerCompareOp (VkCompareOp compareOp); tcu::Sampler::WrapMode mapVkSamplerAddressMode (VkSamplerAddressMode addressMode); tcu::Sampler::FilterMode mapVkMinTexFilter (VkFilter filter, VkSamplerMipmapMode mipMode); tcu::Sampler::FilterMode mapVkMagTexFilter (VkFilter filter); -int mapVkComponentSwizzle (const VkComponentSwizzle& channelSwizzle); -tcu::UVec4 mapVkComponentMapping (const vk::VkComponentMapping& mapping); VkFilter mapFilterMode (tcu::Sampler::FilterMode filterMode); VkSamplerMipmapMode mapMipmapMode (tcu::Sampler::FilterMode filterMode); diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageSamplingInstance.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageSamplingInstance.cpp index f219e2a..606bbb8 100644 --- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageSamplingInstance.cpp +++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageSamplingInstance.cpp @@ -30,7 +30,8 @@ #include "vkPrograms.hpp" #include "vkQueryUtil.hpp" #include "vkRefUtil.hpp" -#include "tcuImageCompare.hpp" +#include "tcuTexLookupVerifier.hpp" +#include "tcuTextureUtil.hpp" #include "deSTLUtil.hpp" namespace vkt @@ -40,6 +41,7 @@ namespace pipeline using namespace vk; using de::MovePtr; +using de::UniquePtr; namespace { @@ -88,7 +90,7 @@ static MovePtr createTestTexture (const TcuFormatType format, VkIma { if (viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) { - if (layerCount == tcu::CUBEFACE_LAST) + if (layerCount == tcu::CUBEFACE_LAST && viewType == VK_IMAGE_VIEW_TYPE_CUBE) { texture = MovePtr(new TestTextureCube(format, size.x())); } @@ -118,214 +120,6 @@ static MovePtr createTestTexture (const TcuFormatType format, VkIma return texture; } -template -static void copySubresourceRange (TcuTextureType& dest, const TcuTextureType& src, const VkImageSubresourceRange& subresourceRange) -{ - DE_ASSERT(subresourceRange.levelCount <= (deUint32)dest.getNumLevels()); - DE_ASSERT(subresourceRange.baseMipLevel + subresourceRange.levelCount <= (deUint32)src.getNumLevels()); - - for (int levelNdx = 0; levelNdx < dest.getNumLevels(); levelNdx++) - { - const tcu::ConstPixelBufferAccess srcLevel (src.getLevel(subresourceRange.baseMipLevel + levelNdx)); - const deUint32 srcLayerOffset = subresourceRange.baseArrayLayer * srcLevel.getWidth() * srcLevel.getHeight() * srcLevel.getFormat().getPixelSize(); - const tcu::ConstPixelBufferAccess srcLevelLayers (srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), subresourceRange.layerCount, (deUint8*)srcLevel.getDataPtr() + srcLayerOffset); - - if (dest.isLevelEmpty(levelNdx)) - dest.allocLevel(levelNdx); - - tcu::copy(dest.getLevel(levelNdx), srcLevelLayers); - } -} - -template<> -void copySubresourceRange (tcu::Texture1DArray& dest, const tcu::Texture1DArray& src, const VkImageSubresourceRange& subresourceRange) -{ - DE_ASSERT(subresourceRange.levelCount <= (deUint32)dest.getNumLevels()); - DE_ASSERT(subresourceRange.baseMipLevel + subresourceRange.levelCount <= (deUint32)src.getNumLevels()); - - DE_ASSERT(subresourceRange.layerCount == (deUint32)dest.getNumLayers()); - DE_ASSERT(subresourceRange.baseArrayLayer + subresourceRange.layerCount <= (deUint32)src.getNumLayers()); - - for (int levelNdx = 0; levelNdx < dest.getNumLevels(); levelNdx++) - { - const tcu::ConstPixelBufferAccess srcLevel (src.getLevel(subresourceRange.baseMipLevel + levelNdx)); - const deUint32 srcLayerOffset = subresourceRange.baseArrayLayer * srcLevel.getWidth() * srcLevel.getFormat().getPixelSize(); - const tcu::ConstPixelBufferAccess srcLevelLayers (srcLevel.getFormat(), srcLevel.getWidth(), subresourceRange.layerCount, 1, (deUint8*)srcLevel.getDataPtr() + srcLayerOffset); - - if (dest.isLevelEmpty(levelNdx)) - dest.allocLevel(levelNdx); - - tcu::copy(dest.getLevel(levelNdx), srcLevelLayers); - } -} - -template<> -void copySubresourceRange(tcu::Texture3D& dest, const tcu::Texture3D& src, const VkImageSubresourceRange& subresourceRange) -{ - DE_ASSERT(subresourceRange.levelCount <= (deUint32)dest.getNumLevels()); - DE_ASSERT(subresourceRange.baseMipLevel + subresourceRange.levelCount <= (deUint32)src.getNumLevels()); - - for (int levelNdx = 0; levelNdx < dest.getNumLevels(); levelNdx++) - { - const tcu::ConstPixelBufferAccess srcLevel(src.getLevel(subresourceRange.baseMipLevel + levelNdx)); - const tcu::ConstPixelBufferAccess srcLevelLayers(srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), srcLevel.getDepth(), (deUint8*)srcLevel.getDataPtr()); - - if (dest.isLevelEmpty(levelNdx)) - dest.allocLevel(levelNdx); - - tcu::copy(dest.getLevel(levelNdx), srcLevelLayers); - } -} - -static MovePtr createRefProgram(const tcu::TextureFormat& renderTargetFormat, - const tcu::Sampler& sampler, - float samplerLod, - const tcu::UVec4& componentMapping, - const TestTexture& testTexture, - VkImageViewType viewType, - int layerCount, - const VkImageSubresourceRange& subresource) -{ - MovePtr program; - const VkImageType imageType = getCompatibleImageType(viewType); - tcu::Vec4 lookupScale (1.0f); - tcu::Vec4 lookupBias (0.0f); - - if (!testTexture.isCompressed()) - { - const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(testTexture.getLevel(0, 0).getFormat()); - - // Needed to normalize various formats to 0..1 range for writing into RT - lookupScale = fmtInfo.lookupScale; - lookupBias = fmtInfo.lookupBias; - } - // else: All supported compressed formats are fine with no normalization. - // ASTC LDR blocks decompress to f16 so querying normalization parameters - // based on uncompressed formats would actually lead to massive precision loss - // and complete lack of coverage in case of R8G8B8A8_UNORM RT. - - switch (imageType) - { - case VK_IMAGE_TYPE_1D: - if (layerCount == 1) - { - const tcu::Texture1D& texture = dynamic_cast(testTexture).getTexture(); - program = MovePtr(new SamplerProgram(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping)); - } - else - { - const tcu::Texture1DArray& texture = dynamic_cast(testTexture).getTexture(); - - if (subresource.baseMipLevel > 0 || subresource.layerCount < (deUint32)texture.getNumLayers()) - { - // Not all texture levels and layers are needed. Create new sub-texture. - const tcu::ConstPixelBufferAccess baseLevel = texture.getLevel(subresource.baseMipLevel); - tcu::Texture1DArray textureView (texture.getFormat(), baseLevel.getWidth(), subresource.layerCount); - - copySubresourceRange(textureView, texture, subresource); - - program = MovePtr(new SamplerProgram(renderTargetFormat, textureView, sampler, samplerLod, lookupScale, lookupBias, componentMapping)); - } - else - { - program = MovePtr(new SamplerProgram(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping)); - } - } - break; - - case VK_IMAGE_TYPE_2D: - if (layerCount == 1) - { - const tcu::Texture2D& texture = dynamic_cast(testTexture).getTexture(); - program = MovePtr(new SamplerProgram(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping)); - } - else - { - if (viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) - { - if (layerCount == tcu::CUBEFACE_LAST) - { - const tcu::TextureCube& texture = dynamic_cast(testTexture).getTexture(); - program = MovePtr(new SamplerProgram(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping)); - } - else - { - DE_ASSERT(layerCount % tcu::CUBEFACE_LAST == 0); - - const tcu::TextureCubeArray& texture = dynamic_cast(testTexture).getTexture(); - - if (subresource.baseMipLevel > 0 || subresource.layerCount < (deUint32)texture.getDepth()) - { - DE_ASSERT(subresource.baseArrayLayer + subresource.layerCount <= (deUint32)texture.getDepth()); - - // Not all texture levels and layers are needed. Create new sub-texture. - const tcu::ConstPixelBufferAccess baseLevel = texture.getLevel(subresource.baseMipLevel); - tcu::TextureCubeArray textureView (texture.getFormat(), baseLevel.getWidth(), subresource.layerCount); - - copySubresourceRange(textureView, texture, subresource); - - program = MovePtr(new SamplerProgram(renderTargetFormat, textureView, sampler, samplerLod, lookupScale, lookupBias, componentMapping)); - } - else - { - // Use all array layers - program = MovePtr(new SamplerProgram(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping)); - } - } - } - else - { - const tcu::Texture2DArray& texture = dynamic_cast(testTexture).getTexture(); - - if (subresource.baseMipLevel > 0 || subresource.layerCount < (deUint32)texture.getNumLayers()) - { - DE_ASSERT(subresource.baseArrayLayer + subresource.layerCount <= (deUint32)texture.getNumLayers()); - - // Not all texture levels and layers are needed. Create new sub-texture. - const tcu::ConstPixelBufferAccess baseLevel = texture.getLevel(subresource.baseMipLevel); - tcu::Texture2DArray textureView (texture.getFormat(), baseLevel.getWidth(), baseLevel.getHeight(), subresource.layerCount); - - copySubresourceRange(textureView, texture, subresource); - - program = MovePtr(new SamplerProgram(renderTargetFormat, textureView, sampler, samplerLod, lookupScale, lookupBias, componentMapping)); - } - else - { - // Use all array layers - program = MovePtr(new SamplerProgram(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping)); - } - } - } - break; - - case VK_IMAGE_TYPE_3D: - { - const tcu::Texture3D& texture = dynamic_cast(testTexture).getTexture(); - - if (subresource.baseMipLevel > 0) - { - // Not all texture levels are needed. Create new sub-texture. - const tcu::ConstPixelBufferAccess baseLevel = texture.getLevel(subresource.baseMipLevel); - tcu::Texture3D textureView(texture.getFormat(), baseLevel.getWidth(), baseLevel.getHeight(), baseLevel.getDepth()); - - copySubresourceRange(textureView, texture, subresource); - - program = MovePtr(new SamplerProgram(renderTargetFormat, textureView, sampler, samplerLod, lookupScale, lookupBias, componentMapping)); - } - else - { - program = MovePtr(new SamplerProgram(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping)); - } - } - break; - - default: - DE_ASSERT(false); - } - - return program; -} - } // anonymous ImageSamplingInstance::ImageSamplingInstance (Context& context, @@ -977,51 +771,612 @@ tcu::TestStatus ImageSamplingInstance::iterate (void) return verifyImage(); } +namespace +{ + +bool isLookupResultValid (const tcu::Texture1DView& texture, + const tcu::Sampler& sampler, + const tcu::LookupPrecision& precision, + const tcu::Vec4& coords, + const tcu::Vec2& lodBounds, + const tcu::Vec4& result) +{ + return tcu::isLookupResultValid(texture, sampler, precision, coords.x(), lodBounds, result); +} + +bool isLookupResultValid (const tcu::Texture1DArrayView& texture, + const tcu::Sampler& sampler, + const tcu::LookupPrecision& precision, + const tcu::Vec4& coords, + const tcu::Vec2& lodBounds, + const tcu::Vec4& result) +{ + return tcu::isLookupResultValid(texture, sampler, precision, coords.swizzle(0,1), lodBounds, result); +} + +bool isLookupResultValid (const tcu::Texture2DView& texture, + const tcu::Sampler& sampler, + const tcu::LookupPrecision& precision, + const tcu::Vec4& coords, + const tcu::Vec2& lodBounds, + const tcu::Vec4& result) +{ + return tcu::isLookupResultValid(texture, sampler, precision, coords.swizzle(0,1), lodBounds, result); +} + +bool isLookupResultValid (const tcu::Texture2DArrayView& texture, + const tcu::Sampler& sampler, + const tcu::LookupPrecision& precision, + const tcu::Vec4& coords, + const tcu::Vec2& lodBounds, + const tcu::Vec4& result) +{ + return tcu::isLookupResultValid(texture, sampler, precision, coords.swizzle(0,1,2), lodBounds, result); +} + +bool isLookupResultValid (const tcu::TextureCubeView& texture, + const tcu::Sampler& sampler, + const tcu::LookupPrecision& precision, + const tcu::Vec4& coords, + const tcu::Vec2& lodBounds, + const tcu::Vec4& result) +{ + return tcu::isLookupResultValid(texture, sampler, precision, coords.swizzle(0,1,2), lodBounds, result); +} + +bool isLookupResultValid (const tcu::TextureCubeArrayView& texture, + const tcu::Sampler& sampler, + const tcu::LookupPrecision& precision, + const tcu::Vec4& coords, + const tcu::Vec2& lodBounds, + const tcu::Vec4& result) +{ + return tcu::isLookupResultValid(texture, sampler, precision, tcu::IVec4(precision.coordBits.x()), coords, lodBounds, result); +} + +bool isLookupResultValid(const tcu::Texture3DView& texture, + const tcu::Sampler& sampler, + const tcu::LookupPrecision& precision, + const tcu::Vec4& coords, + const tcu::Vec2& lodBounds, + const tcu::Vec4& result) +{ + return tcu::isLookupResultValid(texture, sampler, precision, coords.swizzle(0,1,2), lodBounds, result); +} + +template +bool validateResultImage (const TextureViewType& texture, + const tcu::Sampler& sampler, + const tcu::ConstPixelBufferAccess& texCoords, + const tcu::Vec2& lodBounds, + const tcu::LookupPrecision& lookupPrecision, + const tcu::Vec4& lookupScale, + const tcu::Vec4& lookupBias, + const tcu::ConstPixelBufferAccess& result, + const tcu::PixelBufferAccess& errorMask) +{ + const int w = result.getWidth(); + const int h = result.getHeight(); + bool allOk = true; + + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + const tcu::Vec4 resultPixel = result.getPixel(x, y); + const tcu::Vec4 resultColor = (resultPixel - lookupBias) / lookupScale; + const tcu::Vec4 texCoord = texCoords.getPixel(x, y); + const bool pixelOk = isLookupResultValid(texture, sampler, lookupPrecision, texCoord, lodBounds, resultColor); + + errorMask.setPixel(tcu::Vec4(pixelOk?0.0f:1.0f, pixelOk?1.0f:0.0f, 0.0f, 1.0f), x, y); + + if (!pixelOk) + allOk = false; + } + } + + return allOk; +} + +template +ScalarType getSwizzledComp (const tcu::Vector& vec, vk::VkComponentSwizzle comp, int identityNdx) +{ + if (comp == vk::VK_COMPONENT_SWIZZLE_IDENTITY) + return vec[identityNdx]; + else if (comp == vk::VK_COMPONENT_SWIZZLE_ZERO) + return ScalarType(0); + else if (comp == vk::VK_COMPONENT_SWIZZLE_ONE) + return ScalarType(1); + else + return vec[comp - vk::VK_COMPONENT_SWIZZLE_R]; +} + +template +tcu::Vector swizzle (const tcu::Vector& vec, const vk::VkComponentMapping& swz) +{ + return tcu::Vector(getSwizzledComp(vec, swz.r, 0), + getSwizzledComp(vec, swz.g, 1), + getSwizzledComp(vec, swz.b, 2), + getSwizzledComp(vec, swz.a, 3)); +} + +tcu::Vec4 swizzleScaleBias (const tcu::Vec4& vec, const vk::VkComponentMapping& swz) +{ + const float channelValues[] = + { + 1.0f, // -1 + 1.0f, // 0 + 1.0f, + vec.x(), + vec.y(), + vec.z(), + vec.w() + }; + + return tcu::Vec4(channelValues[swz.r], channelValues[swz.g], channelValues[swz.b], channelValues[swz.a]); +} + +template +void swizzleT (const tcu::ConstPixelBufferAccess& src, const tcu::PixelBufferAccess& dst, const vk::VkComponentMapping& swz) +{ + for (int z = 0; z < dst.getDepth(); ++z) + for (int y = 0; y < dst.getHeight(); ++y) + for (int x = 0; x < dst.getWidth(); ++x) + dst.setPixel(swizzle(src.getPixelT(x, y, z), swz), x, y, z); +} + +void swizzleFromSRGB (const tcu::ConstPixelBufferAccess& src, const tcu::PixelBufferAccess& dst, const vk::VkComponentMapping& swz) +{ + for (int z = 0; z < dst.getDepth(); ++z) + for (int y = 0; y < dst.getHeight(); ++y) + for (int x = 0; x < dst.getWidth(); ++x) + dst.setPixel(swizzle(tcu::sRGBToLinear(src.getPixelT(x, y, z)), swz), x, y, z); +} + +void swizzle (const tcu::ConstPixelBufferAccess& src, const tcu::PixelBufferAccess& dst, const vk::VkComponentMapping& swz) +{ + const tcu::TextureChannelClass chnClass = tcu::getTextureChannelClass(dst.getFormat().type); + + DE_ASSERT(src.getWidth() == dst.getWidth() && + src.getHeight() == dst.getHeight() && + src.getDepth() == dst.getDepth()); + + if (chnClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) + swizzleT(src, dst, swz); + else if (chnClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) + swizzleT(src, dst, swz); + else if (tcu::isSRGB(src.getFormat()) && !tcu::isSRGB(dst.getFormat())) + swizzleFromSRGB(src, dst, swz); + else + swizzleT(src, dst, swz); +} + +bool isIdentitySwizzle (const vk::VkComponentMapping& swz) +{ + return (swz.r == vk::VK_COMPONENT_SWIZZLE_IDENTITY || swz.r == vk::VK_COMPONENT_SWIZZLE_R) && + (swz.g == vk::VK_COMPONENT_SWIZZLE_IDENTITY || swz.g == vk::VK_COMPONENT_SWIZZLE_G) && + (swz.b == vk::VK_COMPONENT_SWIZZLE_IDENTITY || swz.b == vk::VK_COMPONENT_SWIZZLE_B) && + (swz.a == vk::VK_COMPONENT_SWIZZLE_IDENTITY || swz.a == vk::VK_COMPONENT_SWIZZLE_A); +} + +template struct TexViewTraits; + +template<> struct TexViewTraits { typedef tcu::Texture1D TextureType; }; +template<> struct TexViewTraits { typedef tcu::Texture1DArray TextureType; }; +template<> struct TexViewTraits { typedef tcu::Texture2D TextureType; }; +template<> struct TexViewTraits { typedef tcu::Texture2DArray TextureType; }; +template<> struct TexViewTraits { typedef tcu::TextureCube TextureType; }; +template<> struct TexViewTraits { typedef tcu::TextureCubeArray TextureType; }; +template<> struct TexViewTraits { typedef tcu::Texture3D TextureType; }; + +template +typename TexViewTraits::TextureType* createSkeletonClone (tcu::TextureFormat format, const tcu::ConstPixelBufferAccess& level0); + +tcu::TextureFormat getSwizzleTargetFormat (tcu::TextureFormat format) +{ + // Swizzled texture needs to hold all four channels + // \todo [2016-09-21 pyry] We could save some memory by using smaller formats + // when possible (for example U8). + + const tcu::TextureChannelClass chnClass = tcu::getTextureChannelClass(format.type); + + if (chnClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) + return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT32); + else if (chnClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) + return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32); + else + return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT); +} + +template<> +tcu::Texture1D* createSkeletonClone (tcu::TextureFormat format, const tcu::ConstPixelBufferAccess& level0) +{ + return new tcu::Texture1D(format, level0.getWidth()); +} + +template<> +tcu::Texture1DArray* createSkeletonClone (tcu::TextureFormat format, const tcu::ConstPixelBufferAccess& level0) +{ + return new tcu::Texture1DArray(format, level0.getWidth(), level0.getHeight()); +} + +template<> +tcu::Texture2D* createSkeletonClone (tcu::TextureFormat format, const tcu::ConstPixelBufferAccess& level0) +{ + return new tcu::Texture2D(format, level0.getWidth(), level0.getHeight()); +} + +template<> +tcu::Texture2DArray* createSkeletonClone (tcu::TextureFormat format, const tcu::ConstPixelBufferAccess& level0) +{ + return new tcu::Texture2DArray(format, level0.getWidth(), level0.getHeight(), level0.getDepth()); +} + +template<> +tcu::Texture3D* createSkeletonClone (tcu::TextureFormat format, const tcu::ConstPixelBufferAccess& level0) +{ + return new tcu::Texture3D(format, level0.getWidth(), level0.getHeight(), level0.getDepth()); +} + +template<> +tcu::TextureCubeArray* createSkeletonClone (tcu::TextureFormat format, const tcu::ConstPixelBufferAccess& level0) +{ + return new tcu::TextureCubeArray(format, level0.getWidth(), level0.getDepth()); +} + +template +MovePtr::TextureType> createSwizzledCopy (const TextureViewType& texture, const vk::VkComponentMapping& swz) +{ + MovePtr::TextureType> copy (createSkeletonClone(getSwizzleTargetFormat(texture.getLevel(0).getFormat()), texture.getLevel(0))); + + for (int levelNdx = 0; levelNdx < texture.getNumLevels(); ++levelNdx) + { + copy->allocLevel(levelNdx); + swizzle(texture.getLevel(levelNdx), copy->getLevel(levelNdx), swz); + } + + return copy; +} + +template<> +MovePtr createSwizzledCopy (const tcu::TextureCubeView& texture, const vk::VkComponentMapping& swz) +{ + MovePtr copy (new tcu::TextureCube(getSwizzleTargetFormat(texture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_X).getFormat()), texture.getSize())); + + for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; ++faceNdx) + { + for (int levelNdx = 0; levelNdx < texture.getNumLevels(); ++levelNdx) + { + copy->allocLevel((tcu::CubeFace)faceNdx, levelNdx); + swizzle(texture.getLevelFace(levelNdx, (tcu::CubeFace)faceNdx), copy->getLevelFace(levelNdx, (tcu::CubeFace)faceNdx), swz); + } + } + + return copy; +} + +template +bool validateResultImage (const TextureViewType& texture, + const tcu::Sampler& sampler, + const vk::VkComponentMapping& swz, + const tcu::ConstPixelBufferAccess& texCoords, + const tcu::Vec2& lodBounds, + const tcu::LookupPrecision& lookupPrecision, + const tcu::Vec4& lookupScale, + const tcu::Vec4& lookupBias, + const tcu::ConstPixelBufferAccess& result, + const tcu::PixelBufferAccess& errorMask) +{ + if (isIdentitySwizzle(swz)) + return validateResultImage(texture, sampler, texCoords, lodBounds, lookupPrecision, lookupScale, lookupBias, result, errorMask); + else + { + // There is (currently) no way to handle swizzling inside validation loop + // and thus we need to pre-swizzle the texture. + UniquePtr::TextureType> swizzledTex (createSwizzledCopy(texture, swz)); + + return validateResultImage(*swizzledTex, sampler, texCoords, lodBounds, lookupPrecision, swizzleScaleBias(lookupScale, swz), swizzleScaleBias(lookupBias, swz), result, errorMask); + } +} + +vk::VkImageSubresourceRange resolveSubresourceRange (const TestTexture& testTexture, const vk::VkImageSubresourceRange& subresource) +{ + vk::VkImageSubresourceRange resolved = subresource; + + if (subresource.levelCount == VK_REMAINING_MIP_LEVELS) + resolved.levelCount = testTexture.getNumLevels()-subresource.baseMipLevel; + + if (subresource.layerCount == VK_REMAINING_ARRAY_LAYERS) + resolved.layerCount = testTexture.getArraySize()-subresource.baseArrayLayer; + + return resolved; +} + +MovePtr getTexture1DView (const TestTexture& testTexture, const vk::VkImageSubresourceRange& subresource, std::vector& levels) +{ + DE_ASSERT(subresource.layerCount == 1); + + levels.resize(subresource.levelCount); + + for (int levelNdx = 0; levelNdx < (int)levels.size(); ++levelNdx) + { + const tcu::ConstPixelBufferAccess& srcLevel = testTexture.getLevel((int)subresource.baseMipLevel+levelNdx, subresource.baseArrayLayer); + + levels[levelNdx] = tcu::getSubregion(srcLevel, 0, 0, 0, srcLevel.getWidth(), 1, 1); + } + + return MovePtr(new tcu::Texture1DView((int)levels.size(), &levels[0])); +} + +MovePtr getTexture1DArrayView (const TestTexture& testTexture, const vk::VkImageSubresourceRange& subresource, std::vector& levels) +{ + const TestTexture1D* tex1D = dynamic_cast(&testTexture); + const TestTexture1DArray* tex1DArray = dynamic_cast(&testTexture); + + DE_ASSERT(!!tex1D != !!tex1DArray); + DE_ASSERT(tex1DArray || subresource.baseArrayLayer == 0); + + levels.resize(subresource.levelCount); + + for (int levelNdx = 0; levelNdx < (int)levels.size(); ++levelNdx) + { + const tcu::ConstPixelBufferAccess& srcLevel = tex1D ? tex1D->getTexture().getLevel((int)subresource.baseMipLevel+levelNdx) + : tex1DArray->getTexture().getLevel((int)subresource.baseMipLevel+levelNdx); + + levels[levelNdx] = tcu::getSubregion(srcLevel, 0, (int)subresource.baseArrayLayer, 0, srcLevel.getWidth(), (int)subresource.layerCount, 1); + } + + return MovePtr(new tcu::Texture1DArrayView((int)levels.size(), &levels[0])); +} + +MovePtr getTexture2DView (const TestTexture& testTexture, const vk::VkImageSubresourceRange& subresource, std::vector& levels) +{ + const TestTexture2D* tex2D = dynamic_cast(&testTexture); + const TestTexture2DArray* tex2DArray = dynamic_cast(&testTexture); + + DE_ASSERT(subresource.layerCount == 1); + DE_ASSERT(!!tex2D != !!tex2DArray); + DE_ASSERT(tex2DArray || subresource.baseArrayLayer == 0); + + levels.resize(subresource.levelCount); + + for (int levelNdx = 0; levelNdx < (int)levels.size(); ++levelNdx) + { + const tcu::ConstPixelBufferAccess& srcLevel = tex2D ? tex2D->getTexture().getLevel((int)subresource.baseMipLevel+levelNdx) + : tex2DArray->getTexture().getLevel((int)subresource.baseMipLevel+levelNdx); + + levels[levelNdx] = tcu::getSubregion(srcLevel, 0, 0, (int)subresource.baseArrayLayer, srcLevel.getWidth(), srcLevel.getHeight(), 1); + } + + return MovePtr(new tcu::Texture2DView((int)levels.size(), &levels[0])); +} + +MovePtr getTexture2DArrayView (const TestTexture& testTexture, const vk::VkImageSubresourceRange& subresource, std::vector& levels) +{ + const TestTexture2D* tex2D = dynamic_cast(&testTexture); + const TestTexture2DArray* tex2DArray = dynamic_cast(&testTexture); + + DE_ASSERT(!!tex2D != !!tex2DArray); + DE_ASSERT(tex2DArray || subresource.baseArrayLayer == 0); + + levels.resize(subresource.levelCount); + + for (int levelNdx = 0; levelNdx < (int)levels.size(); ++levelNdx) + { + const tcu::ConstPixelBufferAccess& srcLevel = tex2D ? tex2D->getTexture().getLevel((int)subresource.baseMipLevel+levelNdx) + : tex2DArray->getTexture().getLevel((int)subresource.baseMipLevel+levelNdx); + + levels[levelNdx] = tcu::getSubregion(srcLevel, 0, 0, (int)subresource.baseArrayLayer, srcLevel.getWidth(), srcLevel.getHeight(), (int)subresource.layerCount); + } + + return MovePtr(new tcu::Texture2DArrayView((int)levels.size(), &levels[0])); +} + +MovePtr getTextureCubeView (const TestTexture& testTexture, const vk::VkImageSubresourceRange& subresource, std::vector& levels) +{ + const static tcu::CubeFace s_faceMap[tcu::CUBEFACE_LAST] = + { + tcu::CUBEFACE_POSITIVE_X, + tcu::CUBEFACE_NEGATIVE_X, + tcu::CUBEFACE_POSITIVE_Y, + tcu::CUBEFACE_NEGATIVE_Y, + tcu::CUBEFACE_POSITIVE_Z, + tcu::CUBEFACE_NEGATIVE_Z + }; + + const TestTextureCube* texCube = dynamic_cast(&testTexture); + const TestTextureCubeArray* texCubeArray = dynamic_cast(&testTexture); + + DE_ASSERT(!!texCube != !!texCubeArray); + DE_ASSERT(subresource.layerCount == 6); + DE_ASSERT(texCubeArray || subresource.baseArrayLayer == 0); + + levels.resize(subresource.levelCount*tcu::CUBEFACE_LAST); + + for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; ++faceNdx) + { + for (int levelNdx = 0; levelNdx < (int)subresource.levelCount; ++levelNdx) + { + const tcu::ConstPixelBufferAccess& srcLevel = texCubeArray ? texCubeArray->getTexture().getLevel((int)subresource.baseMipLevel+levelNdx) + : texCube->getTexture().getLevelFace(levelNdx, s_faceMap[faceNdx]); + + levels[faceNdx*subresource.levelCount + levelNdx] = tcu::getSubregion(srcLevel, 0, 0, (int)subresource.baseArrayLayer + (texCubeArray ? faceNdx : 0), srcLevel.getWidth(), srcLevel.getHeight(), 1); + } + } + + { + const tcu::ConstPixelBufferAccess* reordered[tcu::CUBEFACE_LAST]; + + for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; ++faceNdx) + reordered[s_faceMap[faceNdx]] = &levels[faceNdx*subresource.levelCount]; + + return MovePtr(new tcu::TextureCubeView((int)subresource.levelCount, reordered)); + } +} + +MovePtr getTextureCubeArrayView (const TestTexture& testTexture, const vk::VkImageSubresourceRange& subresource, std::vector& levels) +{ + const TestTextureCubeArray* texCubeArray = dynamic_cast(&testTexture); + + DE_ASSERT(texCubeArray); + DE_ASSERT(subresource.layerCount%6 == 0); + + levels.resize(subresource.levelCount); + + for (int levelNdx = 0; levelNdx < (int)subresource.levelCount; ++levelNdx) + { + const tcu::ConstPixelBufferAccess& srcLevel = texCubeArray->getTexture().getLevel((int)subresource.baseMipLevel+levelNdx); + + levels[levelNdx] = tcu::getSubregion(srcLevel, 0, 0, (int)subresource.baseArrayLayer, srcLevel.getWidth(), srcLevel.getHeight(), (int)subresource.layerCount); + } + + return MovePtr(new tcu::TextureCubeArrayView((int)levels.size(), &levels[0])); +} + +MovePtr getTexture3DView (const TestTexture& testTexture, const vk::VkImageSubresourceRange& subresource, std::vector& levels) +{ + DE_ASSERT(subresource.baseArrayLayer == 0 && subresource.layerCount == 1); + + levels.resize(subresource.levelCount); + + for (int levelNdx = 0; levelNdx < (int)levels.size(); ++levelNdx) + levels[levelNdx] = testTexture.getLevel((int)subresource.baseMipLevel+levelNdx, subresource.baseArrayLayer); + + return MovePtr(new tcu::Texture3DView((int)levels.size(), &levels[0])); +} + +} // anonymous + tcu::TestStatus ImageSamplingInstance::verifyImage (void) { - const tcu::TextureFormat colorFormat = mapVkFormat(m_colorFormat); - const tcu::TextureFormat depthStencilFormat = tcu::TextureFormat(); // Undefined depth/stencil format. - const tcu::Sampler sampler = mapVkSampler(m_samplerParams); - const tcu::UVec4 componentMapping = mapVkComponentMapping(m_componentMapping); - float samplerLod; - bool compareOk; - MovePtr program; - MovePtr refRenderer; - - // Set up LOD of reference sampler - samplerLod = de::max(m_samplerParams.minLod, de::min(m_samplerParams.maxLod, m_samplerParams.mipLodBias + m_samplerLod)); - - // Create reference program that uses image subresource range - program = createRefProgram(colorFormat, sampler, samplerLod, componentMapping, *m_texture, m_imageViewType, m_layerCount, m_subresourceRange); - const rr::Program referenceProgram = program->getReferenceProgram(); - - // Render reference image - refRenderer = MovePtr(new ReferenceRenderer(m_renderSize.x(), m_renderSize.y(), 1, colorFormat, depthStencilFormat, &referenceProgram)); - const rr::RenderState renderState(refRenderer->getViewportState()); - refRenderer->draw(renderState, rr::PRIMITIVETYPE_TRIANGLES, m_vertices); - - // Compare result with reference image + // \note Color buffer is used to capture coordinates - not sampled texture values + const tcu::TextureFormat colorFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT); + const tcu::TextureFormat depthStencilFormat; // Undefined depth/stencil format. + const CoordinateCaptureProgram coordCaptureProgram; + const rr::Program rrProgram = coordCaptureProgram.getReferenceProgram(); + ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, colorFormat, depthStencilFormat, &rrProgram); + + // Read back result image + UniquePtr result (readColorAttachment(m_context.getDeviceInterface(), + m_context.getDevice(), + m_context.getUniversalQueue(), + m_context.getUniversalQueueFamilyIndex(), + m_context.getDefaultAllocator(), + *m_colorImage, + m_colorFormat, + m_renderSize)); + + bool compareOk = true; + + tcu::Vec4 lookupScale (1.0f); + tcu::Vec4 lookupBias (0.0f); + + getLookupScaleBias(m_imageFormat, lookupScale, lookupBias); + + // Render out coordinates + { + const rr::RenderState renderState(refRenderer.getViewportState()); + refRenderer.draw(renderState, rr::PRIMITIVETYPE_TRIANGLES, m_vertices); + } + + // Verify results { - const DeviceInterface& vk = m_context.getDeviceInterface(); - const VkDevice vkDevice = m_context.getDevice(); - const VkQueue queue = m_context.getUniversalQueue(); - const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); - SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice())); - MovePtr result = readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_colorImage, m_colorFormat, m_renderSize); - tcu::UVec4 threshold = tcu::UVec4(4, 4, 4, 4); - - if ((m_imageFormat == vk::VK_FORMAT_EAC_R11G11_SNORM_BLOCK) || (m_imageFormat == vk::VK_FORMAT_EAC_R11_SNORM_BLOCK)) - threshold = tcu::UVec4(8, 8, 8, 8); - - compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(), - "IntImageCompare", - "Image comparison", - refRenderer->getAccess(), - result->getAccess(), - threshold, - tcu::IVec3(1, 1, 0), - true, - tcu::COMPARE_LOG_RESULT); + const tcu::Sampler sampler = mapVkSampler(m_samplerParams); + const float referenceLod = de::clamp(m_samplerParams.mipLodBias + m_samplerLod, m_samplerParams.minLod, m_samplerParams.maxLod); + const float lodError = 1.0f / 255.f; + const tcu::Vec2 lodBounds (referenceLod-lodError, referenceLod+lodError); + const vk::VkImageSubresourceRange subresource = resolveSubresourceRange(*m_texture, m_subresourceRange); + + const tcu::ConstPixelBufferAccess resultAccess = result->getAccess(); + const tcu::ConstPixelBufferAccess coordAccess = refRenderer.getAccess(); + tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), (int)m_renderSize.x(), (int)m_renderSize.y()); + const tcu::PixelBufferAccess errorAccess = errorMask.getAccess(); + + tcu::LookupPrecision lookupPrecision; + + // Set precision requirements - very low for these tests as + // the point of the test is not to validate accuracy. + lookupPrecision.coordBits = tcu::IVec3(17, 17, 17); + lookupPrecision.uvwBits = tcu::IVec3(5, 5, 5); + lookupPrecision.colorMask = tcu::BVec4(true); + lookupPrecision.colorThreshold = tcu::computeFixedPointThreshold(tcu::IVec4(8,8,8,8)) / swizzleScaleBias(lookupScale, m_componentMapping); + + if (tcu::isSRGB(m_texture->getTextureFormat())) + lookupPrecision.colorThreshold += tcu::Vec4(4.f / 255.f); + + switch (m_imageViewType) + { + case VK_IMAGE_VIEW_TYPE_1D: + { + std::vector levels; + UniquePtr texView (getTexture1DView(*m_texture, subresource, levels)); + + compareOk = validateResultImage(*texView, sampler, m_componentMapping, coordAccess, lodBounds, lookupPrecision, lookupScale, lookupBias, resultAccess, errorAccess); + break; + } + + case VK_IMAGE_VIEW_TYPE_1D_ARRAY: + { + std::vector levels; + UniquePtr texView (getTexture1DArrayView(*m_texture, subresource, levels)); + + compareOk = validateResultImage(*texView, sampler, m_componentMapping, coordAccess, lodBounds, lookupPrecision, lookupScale, lookupBias, resultAccess, errorAccess); + break; + } + + case VK_IMAGE_VIEW_TYPE_2D: + { + std::vector levels; + UniquePtr texView (getTexture2DView(*m_texture, subresource, levels)); + + compareOk = validateResultImage(*texView, sampler, m_componentMapping, coordAccess, lodBounds, lookupPrecision, lookupScale, lookupBias, resultAccess, errorAccess); + break; + } + + case VK_IMAGE_VIEW_TYPE_2D_ARRAY: + { + std::vector levels; + UniquePtr texView (getTexture2DArrayView(*m_texture, subresource, levels)); + + compareOk = validateResultImage(*texView, sampler, m_componentMapping, coordAccess, lodBounds, lookupPrecision, lookupScale, lookupBias, resultAccess, errorAccess); + break; + } + + case VK_IMAGE_VIEW_TYPE_CUBE: + { + std::vector levels; + UniquePtr texView (getTextureCubeView(*m_texture, subresource, levels)); + + compareOk = validateResultImage(*texView, sampler, m_componentMapping, coordAccess, lodBounds, lookupPrecision, lookupScale, lookupBias, resultAccess, errorAccess); + break; + } + + case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: + { + std::vector levels; + UniquePtr texView (getTextureCubeArrayView(*m_texture, subresource, levels)); + + compareOk = validateResultImage(*texView, sampler, m_componentMapping, coordAccess, lodBounds, lookupPrecision, lookupScale, lookupBias, resultAccess, errorAccess); + break; + } + + case VK_IMAGE_VIEW_TYPE_3D: + { + std::vector levels; + UniquePtr texView (getTexture3DView(*m_texture, subresource, levels)); + + compareOk = validateResultImage(*texView, sampler, m_componentMapping, coordAccess, lodBounds, lookupPrecision, lookupScale, lookupBias, resultAccess, errorAccess); + break; + } + + default: + DE_ASSERT(false); + } + + if (!compareOk) + m_context.getTestContext().getLog() + << tcu::TestLog::Image("Result", "Result Image", resultAccess) + << tcu::TestLog::Image("ErrorMask", "Error Mask", errorAccess); } if (compareOk) diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageTests.cpp index fbcb8aa..ca11582 100644 --- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageTests.cpp +++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageTests.cpp @@ -92,12 +92,10 @@ void ImageTest::initPrograms (SourceCollections& sourceCollections) const const tcu::TextureFormat format = (isCompressedFormat(m_imageFormat)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(m_imageFormat)) : mapVkFormat(m_imageFormat); - // \note We don't want to perform normalization on any compressed formats. - // In case of non-sRGB LDR ASTC it would lead to lack of coverage - // as uncompressed format for that is f16 but values will be in range - // 0..1 already. - const tcu::TextureFormatInfo formatInfo = (!isCompressedFormat(m_imageFormat) ? tcu::getTextureFormatInfo(format) - : tcu::getTextureFormatInfo(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))); + tcu::Vec4 lookupScale; + tcu::Vec4 lookupBias; + + getLookupScaleBias(m_imageFormat, lookupScale, lookupBias); switch (m_imageViewType) { @@ -140,7 +138,7 @@ void ImageTest::initPrograms (SourceCollections& sourceCollections) const << "layout(location = 0) out highp vec4 fragColor;\n" << "void main (void)\n" << "{\n" - << " fragColor = (texture(texSampler, vtxTexCoords." << texCoordSwizzle << std::scientific << ") * vec4" << formatInfo.lookupScale << ") + vec4" << formatInfo.lookupBias << ";\n" + << " fragColor = (texture(texSampler, vtxTexCoords." << texCoordSwizzle << std::scientific << ") * vec4" << lookupScale << ") + vec4" << lookupBias << ";\n" << "}\n"; sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str()); diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.cpp index 2636258..de720d9 100644 --- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.cpp +++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.cpp @@ -164,6 +164,42 @@ VkBorderColor getFormatBorderColor (BorderColor color, VkFormat format) return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; } +void getLookupScaleBias (vk::VkFormat format, tcu::Vec4& lookupScale, tcu::Vec4& lookupBias) +{ + if (!isCompressedFormat(format)) + { + const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(mapVkFormat(format)); + + // Needed to normalize various formats to 0..1 range for writing into RT + lookupScale = fmtInfo.lookupScale; + lookupBias = fmtInfo.lookupBias; + } + else + { + switch (format) + { + case VK_FORMAT_EAC_R11_SNORM_BLOCK: + lookupScale = tcu::Vec4(0.5f, 1.0f, 1.0f, 1.0f); + lookupBias = tcu::Vec4(0.5f, 0.0f, 0.0f, 0.0f); + break; + + case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: + lookupScale = tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f); + lookupBias = tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f); + break; + + default: + // else: All supported compressed formats are fine with no normalization. + // ASTC LDR blocks decompress to f16 so querying normalization parameters + // based on uncompressed formats would actually lead to massive precision loss + // and complete lack of coverage in case of R8G8B8A8_UNORM RT. + lookupScale = tcu::Vec4(1.0f); + lookupBias = tcu::Vec4(0.0f); + break; + } + } +} + de::MovePtr readColorAttachment (const vk::DeviceInterface& vk, vk::VkDevice device, vk::VkQueue queue, diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.hpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.hpp index c52c380..7c20ccb 100644 --- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.hpp +++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.hpp @@ -59,6 +59,10 @@ bool isLinearFilteringSupported (const vk::InstanceInterface& instanceInte vk::VkBorderColor getFormatBorderColor (BorderColor color, vk::VkFormat format); +void getLookupScaleBias (vk::VkFormat format, + tcu::Vec4& lookupScale, + tcu::Vec4& lookupBias); + /*--------------------------------------------------------------------*//*! * Gets a tcu::TextureLevel initialized with data from a VK color * attachment. diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageViewTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageViewTests.cpp index 2413067..bd44fea 100644 --- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageViewTests.cpp +++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineImageViewTests.cpp @@ -127,15 +127,13 @@ void ImageViewTest::initPrograms (SourceCollections& sourceCollections) const const tcu::TextureFormat format = (isCompressedFormat(m_imageFormat)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(m_imageFormat)) : mapVkFormat(m_imageFormat); - // \note We don't want to perform normalization on any compressed formats. - // In case of non-sRGB LDR ASTC it would lead to lack of coverage - // as uncompressed format for that is f16 but values will be in range - // 0..1 already. - const tcu::TextureFormatInfo formatInfo = (!isCompressedFormat(m_imageFormat) ? tcu::getTextureFormatInfo(format) - : tcu::getTextureFormatInfo(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))); - - tcu::Vec4 swizzledScale = swizzle(formatInfo.lookupScale, m_componentMapping); - tcu::Vec4 swizzledBias = swizzle(formatInfo.lookupBias, m_componentMapping); + tcu::Vec4 lookupScale; + tcu::Vec4 lookupBias; + + getLookupScaleBias(m_imageFormat, lookupScale, lookupBias); + + tcu::Vec4 swizzledScale = swizzle(lookupScale, m_componentMapping); + tcu::Vec4 swizzledBias = swizzle(lookupBias, m_componentMapping); switch (m_imageViewType) { diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineReferenceRenderer.hpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineReferenceRenderer.hpp index 35885bd..4cf3356 100644 --- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineReferenceRenderer.hpp +++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineReferenceRenderer.hpp @@ -162,76 +162,19 @@ public: } }; -template -class SamplerFragmentShader : public rr::FragmentShader +class CoordinateCaptureFragmentShader : public rr::FragmentShader { -private: - const tcu::TextureFormat m_colorFormat; - const tcu::TextureFormatInfo m_colorFormatInfo; - const TextureType m_texture; - const tcu::Sampler m_sampler; - const float m_lod; - const tcu::Vec4 m_lookupScale; - const tcu::Vec4 m_lookupBias; - const tcu::UVec4 m_swizzle; - public: - SamplerFragmentShader (const tcu::TextureFormat& colorFormat, const TextureType& texture, const tcu::Sampler& sampler, float lod, const tcu::Vec4& lookupScale, const tcu::Vec4& lookupBias, const tcu::UVec4& swizzle) - : rr::FragmentShader (2, 1) - , m_colorFormat (colorFormat) - , m_colorFormatInfo (tcu::getTextureFormatInfo(m_colorFormat)) - , m_texture (texture) - , m_sampler (sampler) - , m_lod (lod) - , m_lookupScale (lookupScale) - , m_lookupBias (lookupBias) - , m_swizzle (swizzle) + CoordinateCaptureFragmentShader (void) + : rr::FragmentShader(2, 1) { - const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(m_colorFormat.type); m_inputs[0].type = rr::GENERICVECTYPE_FLOAT; m_inputs[1].type = rr::GENERICVECTYPE_FLOAT; - m_outputs[0].type = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)? rr::GENERICVECTYPE_INT32 : - (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)? rr::GENERICVECTYPE_UINT32 - : rr::GENERICVECTYPE_FLOAT; - } - - virtual ~SamplerFragmentShader (void) - { - } - - static tcu::Vec4 sampleTexture (const tcu::Texture1D& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod) - { - return texture.sample(sampler, texCoord.x(), lod); - } - - static tcu::Vec4 sampleTexture (const tcu::Texture1DArray& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod) - { - return texture.sample(sampler, texCoord.x(), texCoord.y(), lod); - } - - static tcu::Vec4 sampleTexture (const tcu::Texture2D& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod) - { - return texture.sample(sampler, texCoord.x(), texCoord.y(), lod); - } - - static tcu::Vec4 sampleTexture (const tcu::Texture2DArray& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod) - { - return texture.sample(sampler, texCoord.x(), texCoord.y(), texCoord.z(), lod); - } - - static tcu::Vec4 sampleTexture (const tcu::Texture3D& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod) - { - return texture.sample(sampler, texCoord.x(), texCoord.y(), texCoord.z(), lod); - } - - static tcu::Vec4 sampleTexture (const tcu::TextureCube& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod) - { - return texture.sample(sampler, texCoord.x(), texCoord.y(), texCoord.z(), lod); + m_outputs[0].type = rr::GENERICVECTYPE_FLOAT; } - static tcu::Vec4 sampleTexture (const tcu::TextureCubeArray& texture, const tcu::Sampler& sampler, const tcu::Vec4& texCoord, float lod) + virtual ~CoordinateCaptureFragmentShader (void) { - return texture.sample(sampler, texCoord.x(), texCoord.y(), texCoord.z(), texCoord.w(), lod); } virtual void shadeFragments (rr::FragmentPacket* packets, @@ -245,11 +188,7 @@ public: for (int fragNdx = 0; fragNdx < 4; fragNdx++) { const tcu::Vec4 vtxTexCoord = rr::readVarying(packet, context, 1, fragNdx); - const tcu::Vec4 texColor = sampleTexture(m_texture, m_sampler, vtxTexCoord, m_lod); - const tcu::Vec4 normColor = texColor * m_lookupScale + m_lookupBias; - const tcu::Vec4 swizColor = swizzle(normColor, m_swizzle); - const tcu::Vec4 color = (swizColor + m_colorFormatInfo.lookupBias) / m_colorFormatInfo.lookupScale; - rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color); + rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, vtxTexCoord); } } } @@ -263,20 +202,17 @@ public: virtual rr::Program getReferenceProgram (void) const = 0; }; -template -class SamplerProgram: public Program +class CoordinateCaptureProgram : public Program { private: - TexCoordVertexShader m_vertexShader; - SamplerFragmentShader m_fragmentShader; + TexCoordVertexShader m_vertexShader; + CoordinateCaptureFragmentShader m_fragmentShader; public: - SamplerProgram (const tcu::TextureFormat& colorFormat, const TextureType& texture, const tcu::Sampler& sampler, float lod, const tcu::Vec4& lookupScale, const tcu::Vec4& lookupBias, const tcu::UVec4& swizzle) - : m_vertexShader () - , m_fragmentShader (colorFormat, texture, sampler, lod, lookupScale, lookupBias, swizzle) + CoordinateCaptureProgram (void) { } - virtual ~SamplerProgram (void) { } + virtual ~CoordinateCaptureProgram (void) { } virtual rr::Program getReferenceProgram (void) const { diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineSamplerTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineSamplerTests.cpp index cb49f9f..dd2bb52 100644 --- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineSamplerTests.cpp +++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineSamplerTests.cpp @@ -184,13 +184,10 @@ void SamplerTest::initPrograms (SourceCollections& sourceCollections) const const char* texCoordSwizzle = DE_NULL; tcu::TextureFormat format = (isCompressedFormat(m_imageFormat)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(m_imageFormat)) : mapVkFormat(m_imageFormat); + tcu::Vec4 lookupScale; + tcu::Vec4 lookupBias; - // \note We don't want to perform normalization on any compressed formats. - // In case of non-sRGB LDR ASTC it would lead to lack of coverage - // as uncompressed format for that is f16 but values will be in range - // 0..1 already. - const tcu::TextureFormatInfo formatInfo = (!isCompressedFormat(m_imageFormat) ? tcu::getTextureFormatInfo(format) - : tcu::getTextureFormatInfo(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))); + getLookupScaleBias(m_imageFormat, lookupScale, lookupBias); switch (m_imageViewType) { @@ -240,7 +237,7 @@ void SamplerTest::initPrograms (SourceCollections& sourceCollections) const else fragmentSrc << "texture(texSampler, vtxTexCoords." << texCoordSwizzle << ")" << std::fixed; - fragmentSrc << " * vec4" << std::scientific << formatInfo.lookupScale << " + vec4" << formatInfo.lookupBias << ";\n" + fragmentSrc << " * vec4" << std::scientific << lookupScale << " + vec4" << lookupBias << ";\n" << "}\n"; sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str()); -- 2.7.4