| /*------------------------------------------------------------------------ |
| * Vulkan Conformance Tests |
| * ------------------------ |
| * |
| * Copyright (c) 2017 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 vktImageCompressionTranscodingSupport.cpp |
| * \brief Compression transcoding support |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "vktImageCompressionTranscodingSupport.hpp" |
| |
| #include "deUniquePtr.hpp" |
| #include "deStringUtil.hpp" |
| #include "deSharedPtr.hpp" |
| #include "deRandom.hpp" |
| |
| #include "vktTestCaseUtil.hpp" |
| #include "vkPrograms.hpp" |
| #include "vkImageUtil.hpp" |
| #include "vktImageTestsUtil.hpp" |
| #include "vkBuilderUtil.hpp" |
| #include "vkRef.hpp" |
| #include "vkRefUtil.hpp" |
| #include "vkTypeUtil.hpp" |
| #include "vkQueryUtil.hpp" |
| |
| #include "tcuTextureUtil.hpp" |
| #include "tcuTexture.hpp" |
| #include "tcuCompressedTexture.hpp" |
| #include "tcuVectorType.hpp" |
| #include "tcuResource.hpp" |
| #include "tcuImageIO.hpp" |
| #include "tcuImageCompare.hpp" |
| #include "tcuTestLog.hpp" |
| #include "tcuRGBA.hpp" |
| #include "tcuSurface.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 tcu::Resource; |
| using tcu::Archive; |
| using tcu::ConstPixelBufferAccess; |
| using de::MovePtr; |
| using de::SharedPtr; |
| using de::Random; |
| |
| typedef SharedPtr<MovePtr<Image> > ImageSp; |
| typedef SharedPtr<Move<VkImageView> > ImageViewSp; |
| typedef SharedPtr<Move<VkDescriptorSet> > SharedVkDescriptorSet; |
| |
| enum ShaderType |
| { |
| SHADER_TYPE_COMPUTE, |
| SHADER_TYPE_FRAGMENT, |
| SHADER_TYPE_LAST |
| }; |
| |
| enum Operation |
| { |
| OPERATION_IMAGE_LOAD, |
| OPERATION_TEXEL_FETCH, |
| OPERATION_TEXTURE, |
| OPERATION_IMAGE_STORE, |
| OPERATION_ATTACHMENT_READ, |
| OPERATION_ATTACHMENT_WRITE, |
| OPERATION_TEXTURE_READ, |
| OPERATION_TEXTURE_WRITE, |
| OPERATION_LAST |
| }; |
| |
| struct TestParameters |
| { |
| Operation operation; |
| ShaderType shader; |
| UVec3 size; |
| ImageType imageType; |
| VkFormat formatCompressed; |
| VkFormat formatUncompressed; |
| deUint32 imagesCount; |
| VkImageUsageFlags compressedImageUsage; |
| VkImageUsageFlags compressedImageViewUsage; |
| VkImageUsageFlags uncompressedImageUsage; |
| bool useMipmaps; |
| VkFormat formatForVerify; |
| }; |
| |
| template<typename T> |
| inline SharedPtr<Move<T> > makeVkSharedPtr (Move<T> move) |
| { |
| return SharedPtr<Move<T> >(new Move<T>(move)); |
| } |
| |
| template<typename T> |
| inline SharedPtr<MovePtr<T> > makeVkSharedPtr (MovePtr<T> movePtr) |
| { |
| return SharedPtr<MovePtr<T> >(new MovePtr<T>(movePtr)); |
| } |
| |
| const deUint32 SINGLE_LEVEL = 1u; |
| const deUint32 SINGLE_LAYER = 1u; |
| |
| class BasicTranscodingTestInstance : public TestInstance |
| { |
| public: |
| BasicTranscodingTestInstance (Context& context, |
| const TestParameters& parameters); |
| virtual TestStatus iterate (void) = 0; |
| protected: |
| void generateData (deUint8* toFill, |
| const size_t size, |
| const VkFormat format, |
| const deUint32 layer = 0u, |
| const deUint32 level = 0u); |
| deUint32 getLevelCount (); |
| deUint32 getLayerCount (); |
| UVec3 getLayerDims (); |
| vector<UVec3> getMipLevelSizes (UVec3 baseSize); |
| vector<UVec3> getCompressedMipLevelSizes (const VkFormat compressedFormat, |
| const vector<UVec3>& uncompressedSizes); |
| |
| const TestParameters m_parameters; |
| const deUint32 m_blockWidth; |
| const deUint32 m_blockHeight; |
| const deUint32 m_levelCount; |
| const UVec3 m_layerSize; |
| |
| private: |
| deUint32 findMipMapLevelCount (); |
| }; |
| |
| deUint32 BasicTranscodingTestInstance::findMipMapLevelCount () |
| { |
| deUint32 levelCount = 1; |
| |
| // We cannot use mipmap levels which have resolution below block size. |
| // Reduce number of mipmap levels |
| if (m_parameters.useMipmaps) |
| { |
| deUint32 w = m_parameters.size.x(); |
| deUint32 h = m_parameters.size.y(); |
| |
| DE_ASSERT(m_blockWidth > 0u && m_blockHeight > 0u); |
| |
| while (w > m_blockWidth && h > m_blockHeight) |
| { |
| w >>= 1; |
| h >>= 1; |
| |
| if (w > m_blockWidth && h > m_blockHeight) |
| levelCount++; |
| } |
| |
| DE_ASSERT((m_parameters.size.x() >> (levelCount - 1u)) >= m_blockWidth); |
| DE_ASSERT((m_parameters.size.y() >> (levelCount - 1u)) >= m_blockHeight); |
| } |
| |
| return levelCount; |
| } |
| |
| BasicTranscodingTestInstance::BasicTranscodingTestInstance (Context& context, const TestParameters& parameters) |
| : TestInstance (context) |
| , m_parameters (parameters) |
| , m_blockWidth (getBlockWidth(m_parameters.formatCompressed)) |
| , m_blockHeight (getBlockHeight(m_parameters.formatCompressed)) |
| , m_levelCount (findMipMapLevelCount()) |
| , m_layerSize (getLayerSize(m_parameters.imageType, m_parameters.size)) |
| { |
| DE_ASSERT(deLog2Floor32(m_parameters.size.x()) == deLog2Floor32(m_parameters.size.y())); |
| } |
| |
| deUint32 BasicTranscodingTestInstance::getLevelCount() |
| { |
| return m_levelCount; |
| } |
| |
| deUint32 BasicTranscodingTestInstance::getLayerCount() |
| { |
| return m_parameters.size.z(); |
| } |
| |
| UVec3 BasicTranscodingTestInstance::getLayerDims() |
| { |
| return m_layerSize; |
| } |
| |
| vector<UVec3> BasicTranscodingTestInstance::getMipLevelSizes (UVec3 baseSize) |
| { |
| vector<UVec3> levelSizes; |
| const deUint32 levelCount = getLevelCount(); |
| |
| DE_ASSERT(m_parameters.imageType == IMAGE_TYPE_2D || m_parameters.imageType == IMAGE_TYPE_2D_ARRAY); |
| |
| baseSize.z() = 1u; |
| |
| levelSizes.push_back(baseSize); |
| |
| while (levelSizes.size() < levelCount && (baseSize.x() != 1 || baseSize.y() != 1)) |
| { |
| baseSize.x() = deMax32(baseSize.x() >> 1, 1); |
| baseSize.y() = deMax32(baseSize.y() >> 1, 1); |
| levelSizes.push_back(baseSize); |
| } |
| |
| DE_ASSERT(levelSizes.size() == getLevelCount()); |
| |
| return levelSizes; |
| } |
| |
| vector<UVec3> BasicTranscodingTestInstance::getCompressedMipLevelSizes (const VkFormat compressedFormat, const vector<UVec3>& uncompressedSizes) |
| { |
| vector<UVec3> levelSizes; |
| vector<UVec3>::const_iterator it; |
| |
| for (it = uncompressedSizes.begin(); it != uncompressedSizes.end(); it++) |
| levelSizes.push_back(getCompressedImageResolutionInBlocks(compressedFormat, *it)); |
| |
| return levelSizes; |
| } |
| |
| void BasicTranscodingTestInstance::generateData (deUint8* toFill, |
| const size_t size, |
| const VkFormat format, |
| const deUint32 layer, |
| const deUint32 level) |
| { |
| const deUint8 pattern[] = |
| { |
| // 64-bit values |
| 0x11, 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x22, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, |
| 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Positive infinity |
| 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Negative infinity |
| 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // Start of a signalling NaN (NANS) |
| 0x7F, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // End of a signalling NaN (NANS) |
| 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // Start of a signalling NaN (NANS) |
| 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // End of a signalling NaN (NANS) |
| 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Start of a quiet NaN (NANQ) |
| 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // End of of a quiet NaN (NANQ) |
| 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Start of a quiet NaN (NANQ) |
| 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // End of a quiet NaN (NANQ) |
| // 32-bit values |
| 0x7F, 0x80, 0x00, 0x00, // Positive infinity |
| 0xFF, 0x80, 0x00, 0x00, // Negative infinity |
| 0x7F, 0x80, 0x00, 0x01, // Start of a signalling NaN (NANS) |
| 0x7F, 0xBF, 0xFF, 0xFF, // End of a signalling NaN (NANS) |
| 0xFF, 0x80, 0x00, 0x01, // Start of a signalling NaN (NANS) |
| 0xFF, 0xBF, 0xFF, 0xFF, // End of a signalling NaN (NANS) |
| 0x7F, 0xC0, 0x00, 0x00, // Start of a quiet NaN (NANQ) |
| 0x7F, 0xFF, 0xFF, 0xFF, // End of of a quiet NaN (NANQ) |
| 0xFF, 0xC0, 0x00, 0x00, // Start of a quiet NaN (NANQ) |
| 0xFF, 0xFF, 0xFF, 0xFF, // End of a quiet NaN (NANQ) |
| 0xAA, 0xAA, 0xAA, 0xAA, |
| 0x55, 0x55, 0x55, 0x55, |
| }; |
| |
| deUint8* start = toFill; |
| size_t sizeToRnd = size; |
| |
| // Pattern part |
| if (layer == 0 && level == 0 && size >= 2 * sizeof(pattern)) |
| { |
| // Rotated pattern |
| for (size_t i = 0; i < sizeof(pattern); i++) |
| start[sizeof(pattern) - i - 1] = pattern[i]; |
| |
| start += sizeof(pattern); |
| sizeToRnd -= sizeof(pattern); |
| |
| // Direct pattern |
| deMemcpy(start, pattern, sizeof(pattern)); |
| |
| start += sizeof(pattern); |
| sizeToRnd -= sizeof(pattern); |
| } |
| |
| // Random part |
| { |
| DE_ASSERT(sizeToRnd % sizeof(deUint32) == 0); |
| |
| deUint32* start32 = reinterpret_cast<deUint32*>(start); |
| size_t sizeToRnd32 = sizeToRnd / 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(); |
| } |
| |
| { |
| // Remove certain values that may not be preserved based on the uncompressed view format |
| if (isSnormFormat(m_parameters.formatUncompressed)) |
| { |
| for (size_t i = 0; i < size; i += 2) |
| { |
| // SNORM fix: due to write operation in SNORM format |
| // replaces 0x00 0x80 to 0x01 0x80 |
| if (toFill[i] == 0x00 && toFill[i+1] == 0x80) |
| toFill[i+1] = 0x81; |
| } |
| } |
| else if (isFloatFormat(m_parameters.formatUncompressed)) |
| { |
| tcu::TextureFormat textureFormat = mapVkFormat(m_parameters.formatUncompressed); |
| |
| if (textureFormat.type == tcu::TextureFormat::HALF_FLOAT) |
| { |
| for (size_t i = 0; i < size; i += 2) |
| { |
| // HALF_FLOAT fix: remove INF and NaN |
| if ((toFill[i+1] & 0x7C) == 0x7C) |
| toFill[i+1] = 0x00; |
| } |
| } |
| else if (textureFormat.type == tcu::TextureFormat::FLOAT) |
| { |
| for (size_t i = 0; i < size; i += 4) |
| { |
| // HALF_FLOAT fix: remove INF and NaN |
| if ((toFill[i+1] & 0x7C) == 0x7C) |
| toFill[i+1] = 0x00; |
| } |
| |
| for (size_t i = 0; i < size; i += 4) |
| { |
| // FLOAT fix: remove INF, NaN, and denorm |
| // Little endian fix |
| if (((toFill[i+3] & 0x7F) == 0x7F && (toFill[i+2] & 0x80) == 0x80) || ((toFill[i+3] & 0x7F) == 0x00 && (toFill[i+2] & 0x80) == 0x00)) |
| toFill[i+3] = 0x01; |
| // Big endian fix |
| if (((toFill[i+0] & 0x7F) == 0x7F && (toFill[i+1] & 0x80) == 0x80) || ((toFill[i+0] & 0x7F) == 0x00 && (toFill[i+1] & 0x80) == 0x00)) |
| toFill[i+0] = 0x01; |
| } |
| } |
| } |
| } |
| } |
| |
| class BasicComputeTestInstance : public BasicTranscodingTestInstance |
| { |
| public: |
| BasicComputeTestInstance (Context& context, |
| const TestParameters& parameters); |
| TestStatus iterate (void); |
| protected: |
| struct ImageData |
| { |
| deUint32 getImagesCount (void) { return static_cast<deUint32>(images.size()); } |
| deUint32 getImageViewCount (void) { return static_cast<deUint32>(imagesViews.size()); } |
| deUint32 getImageInfoCount (void) { return static_cast<deUint32>(imagesInfos.size()); } |
| VkImage getImage (const deUint32 ndx) { return **images[ndx]->get(); } |
| VkImageView getImageView (const deUint32 ndx) { return **imagesViews[ndx]; } |
| VkImageCreateInfo getImageInfo (const deUint32 ndx) { return imagesInfos[ndx]; } |
| void addImage (MovePtr<Image> image) { images.push_back(makeVkSharedPtr(image)); } |
| void addImageView (Move<VkImageView> imageView) { imagesViews.push_back(makeVkSharedPtr(imageView));} |
| void addImageInfo (const VkImageCreateInfo imageInfo) { imagesInfos.push_back(imageInfo); } |
| void resetViews () { imagesViews.clear(); } |
| private: |
| vector<ImageSp> images; |
| vector<ImageViewSp> imagesViews; |
| vector<VkImageCreateInfo> imagesInfos; |
| }; |
| void copyDataToImage (const VkCommandBuffer& cmdBuffer, |
| ImageData& imageData, |
| const vector<UVec3>& mipMapSizes, |
| const bool isCompressed); |
| virtual void executeShader (const VkCommandBuffer& cmdBuffer, |
| const VkDescriptorSetLayout& descriptorSetLayout, |
| const VkDescriptorPool& descriptorPool, |
| vector<ImageData>& imageData); |
| bool copyResultAndCompare (const VkCommandBuffer& cmdBuffer, |
| const VkImage& uncompressed, |
| const VkDeviceSize offset, |
| const UVec3& size); |
| void descriptorSetUpdate (VkDescriptorSet descriptorSet, |
| const VkDescriptorImageInfo* descriptorImageInfos); |
| void createImageInfos (ImageData& imageData, |
| const vector<UVec3>& mipMapSizes, |
| const bool isCompressed); |
| bool decompressImage (const VkCommandBuffer& cmdBuffer, |
| vector<ImageData>& imageData, |
| const vector<UVec3>& mipMapSizes); |
| vector<deUint8> m_data; |
| }; |
| |
| |
| BasicComputeTestInstance::BasicComputeTestInstance (Context& context, const TestParameters& parameters) |
| :BasicTranscodingTestInstance (context, parameters) |
| { |
| } |
| |
| TestStatus BasicComputeTestInstance::iterate (void) |
| { |
| const DeviceInterface& vk = m_context.getDeviceInterface(); |
| const VkDevice device = m_context.getDevice(); |
| const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); |
| Allocator& allocator = m_context.getDefaultAllocator(); |
| 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 vector<UVec3> mipMapSizes = m_parameters.useMipmaps ? getMipLevelSizes (getLayerDims()) : vector<UVec3>(1, m_parameters.size); |
| vector<ImageData> imageData (m_parameters.imagesCount); |
| const deUint32 compressedNdx = 0u; |
| const deUint32 resultImageNdx = m_parameters.imagesCount -1u; |
| |
| for (deUint32 imageNdx = 0u; imageNdx < m_parameters.imagesCount; ++imageNdx) |
| { |
| const bool isCompressed = compressedNdx == imageNdx ? true : false; |
| createImageInfos(imageData[imageNdx], mipMapSizes, isCompressed); |
| for (deUint32 infoNdx = 0u; infoNdx < imageData[imageNdx].getImageInfoCount(); ++infoNdx) |
| { |
| imageData[imageNdx].addImage(MovePtr<Image>(new Image(vk, device, allocator, imageData[imageNdx].getImageInfo(infoNdx), MemoryRequirement::Any))); |
| if (isCompressed) |
| { |
| const VkImageViewUsageCreateInfoKHR imageViewUsageKHR = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, //VkStructureType sType; |
| DE_NULL, //const void* pNext; |
| m_parameters.compressedImageUsage, //VkImageUsageFlags usage; |
| }; |
| for (deUint32 mipNdx = 0u; mipNdx < mipMapSizes.size(); ++mipNdx) |
| for (deUint32 layerNdx = 0u; layerNdx < getLayerCount(); ++layerNdx) |
| { |
| imageData[imageNdx].addImageView(makeImageView(vk, device, imageData[imageNdx].getImage(infoNdx), |
| mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed, |
| makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipNdx, 1u, layerNdx, 1u), |
| &imageViewUsageKHR)); |
| } |
| } |
| else |
| { |
| imageData[imageNdx].addImageView(makeImageView(vk, device, imageData[imageNdx].getImage(infoNdx), |
| mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed, |
| makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))); |
| } |
| } |
| } |
| |
| { |
| size_t size = 0ull; |
| for(deUint32 mipNdx = 0u; mipNdx < mipMapSizes.size(); ++mipNdx) |
| { |
| size += static_cast<size_t>(getCompressedImageSizeInBytes(m_parameters.formatCompressed, mipMapSizes[mipNdx]) * getLayerCount()); |
| } |
| m_data.resize(size); |
| generateData (&m_data[0], m_data.size(), m_parameters.formatCompressed); |
| } |
| |
| switch(m_parameters.operation) |
| { |
| case OPERATION_IMAGE_LOAD: |
| case OPERATION_TEXEL_FETCH: |
| case OPERATION_TEXTURE: |
| copyDataToImage(*cmdBuffer, imageData[compressedNdx], mipMapSizes, true); |
| break; |
| case OPERATION_IMAGE_STORE: |
| copyDataToImage(*cmdBuffer, imageData[1], mipMapSizes, false); |
| break; |
| default: |
| DE_ASSERT(false); |
| break; |
| } |
| |
| { |
| Move<VkDescriptorSetLayout> descriptorSetLayout; |
| Move<VkDescriptorPool> descriptorPool; |
| |
| DescriptorSetLayoutBuilder descriptorSetLayoutBuilder; |
| DescriptorPoolBuilder descriptorPoolBuilder; |
| for (deUint32 imageNdx = 0u; imageNdx < m_parameters.imagesCount; ++imageNdx) |
| { |
| switch(m_parameters.operation) |
| { |
| case OPERATION_IMAGE_LOAD: |
| case OPERATION_IMAGE_STORE: |
| descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); |
| descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, imageData[0].getImageViewCount()); |
| break; |
| case OPERATION_TEXEL_FETCH: |
| case OPERATION_TEXTURE: |
| descriptorSetLayoutBuilder.addSingleBinding((compressedNdx == imageNdx) ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); |
| descriptorPoolBuilder.addType((compressedNdx == imageNdx) ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, imageData[0].getImageViewCount()); |
| break; |
| default: |
| DE_ASSERT(false); |
| break; |
| } |
| } |
| descriptorSetLayout = descriptorSetLayoutBuilder.build(vk, device); |
| descriptorPool = descriptorPoolBuilder.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, imageData[0].getImageViewCount()); |
| executeShader(*cmdBuffer, *descriptorSetLayout, *descriptorPool, imageData); |
| |
| { |
| VkDeviceSize offset = 0ull; |
| for (deUint32 mipNdx = 0u; mipNdx < mipMapSizes.size(); ++mipNdx) |
| for (deUint32 layerNdx = 0u; layerNdx < getLayerCount(); ++layerNdx) |
| { |
| const deUint32 imageNdx = layerNdx + mipNdx * getLayerCount(); |
| const UVec3 size = UVec3(imageData[resultImageNdx].getImageInfo(imageNdx).extent.width, |
| imageData[resultImageNdx].getImageInfo(imageNdx).extent.height, |
| imageData[resultImageNdx].getImageInfo(imageNdx).extent.depth); |
| if (!copyResultAndCompare(*cmdBuffer, imageData[resultImageNdx].getImage(imageNdx), offset, size)) |
| return TestStatus::fail("Fail"); |
| offset += getCompressedImageSizeInBytes(m_parameters.formatCompressed, mipMapSizes[mipNdx]); |
| } |
| } |
| }; |
| if (!decompressImage(*cmdBuffer, imageData, mipMapSizes)) |
| return TestStatus::fail("Fail"); |
| return TestStatus::pass("Pass"); |
| } |
| |
| void BasicComputeTestInstance::copyDataToImage (const VkCommandBuffer& cmdBuffer, |
| ImageData& imageData, |
| const vector<UVec3>& mipMapSizes, |
| const bool isCompressed) |
| { |
| const DeviceInterface& vk = m_context.getDeviceInterface(); |
| const VkDevice device = m_context.getDevice(); |
| const VkQueue queue = m_context.getUniversalQueue(); |
| Allocator& allocator = m_context.getDefaultAllocator(); |
| |
| Buffer imageBuffer (vk, device, allocator, |
| makeBufferCreateInfo(m_data.size(), VK_BUFFER_USAGE_TRANSFER_SRC_BIT), |
| MemoryRequirement::HostVisible); |
| VkDeviceSize offset = 0ull; |
| { |
| const Allocation& alloc = imageBuffer.getAllocation(); |
| deMemcpy(alloc.getHostPtr(), &m_data[0], m_data.size()); |
| flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), m_data.size()); |
| } |
| |
| beginCommandBuffer(vk, cmdBuffer); |
| const VkImageSubresourceRange subresourceRange = |
| { |
| VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask |
| 0u, //deUint32 baseMipLevel |
| imageData.getImageInfo(0u).mipLevels, //deUint32 levelCount |
| 0u, //deUint32 baseArrayLayer |
| imageData.getImageInfo(0u).arrayLayers //deUint32 layerCount |
| }; |
| |
| for (deUint32 imageNdx = 0u; imageNdx < imageData.getImagesCount(); ++imageNdx) |
| { |
| const VkImageMemoryBarrier preCopyImageBarrier = makeImageMemoryBarrier( |
| 0u, VK_ACCESS_TRANSFER_WRITE_BIT, |
| VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, |
| imageData.getImage(imageNdx), subresourceRange); |
| |
| const VkBufferMemoryBarrier FlushHostCopyBarrier = makeBufferMemoryBarrier( |
| VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, |
| imageBuffer.get(), 0ull, m_data.size()); |
| |
| vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, |
| (VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 1u, &FlushHostCopyBarrier, 1u, &preCopyImageBarrier); |
| |
| for (deUint32 mipNdx = 0u; mipNdx < imageData.getImageInfo(imageNdx).mipLevels; ++mipNdx) |
| { |
| const VkExtent3D imageExtent = isCompressed ? |
| makeExtent3D(mipMapSizes[mipNdx]) : |
| imageData.getImageInfo(imageNdx).extent; |
| const VkBufferImageCopy copyRegion = |
| { |
| offset, //VkDeviceSize bufferOffset; |
| 0u, //deUint32 bufferRowLength; |
| 0u, //deUint32 bufferImageHeight; |
| makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, mipNdx, 0u, imageData.getImageInfo(imageNdx).arrayLayers), //VkImageSubresourceLayers imageSubresource; |
| makeOffset3D(0, 0, 0), //VkOffset3D imageOffset; |
| imageExtent, //VkExtent3D imageExtent; |
| }; |
| |
| vk.cmdCopyBufferToImage(cmdBuffer, imageBuffer.get(), imageData.getImage(imageNdx), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region); |
| offset += getCompressedImageSizeInBytes(m_parameters.formatCompressed, |
| UVec3(isCompressed ? imageExtent.width : imageExtent.width * m_blockWidth, isCompressed? imageExtent.height :imageExtent.height * m_blockHeight,imageExtent.depth)) * |
| imageData.getImageInfo(imageNdx).arrayLayers; |
| } |
| } |
| endCommandBuffer(vk, cmdBuffer); |
| submitCommandsAndWait(vk, device, queue, cmdBuffer); |
| } |
| |
| void BasicComputeTestInstance::executeShader (const VkCommandBuffer& cmdBuffer, |
| const VkDescriptorSetLayout& descriptorSetLayout, |
| const VkDescriptorPool& descriptorPool, |
| vector<ImageData>& imageData) |
| { |
| const DeviceInterface& vk = m_context.getDeviceInterface(); |
| const VkDevice device = m_context.getDevice(); |
| const VkQueue queue = m_context.getUniversalQueue(); |
| const Unique<VkShaderModule> shaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0)); |
| vector<SharedVkDescriptorSet> descriptorSets (imageData[0].getImageViewCount()); |
| const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, descriptorSetLayout)); |
| const Unique<VkPipeline> pipeline (makeComputePipeline(vk, device, *pipelineLayout, *shaderModule)); |
| Move<VkSampler> sampler; |
| { |
| 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; |
| 0.0f, //float maxLod; |
| VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, //VkBorderColor borderColor; |
| VK_FALSE, //VkBool32 unnormalizedCoordinates; |
| }; |
| sampler = createSampler(vk, device, &createInfo); |
| } |
| |
| vector<VkDescriptorImageInfo> descriptorImageInfos (descriptorSets.size() * m_parameters.imagesCount); |
| for (deUint32 viewNdx = 0u; viewNdx < descriptorSets.size(); ++viewNdx) |
| { |
| const deUint32 descriptorNdx = viewNdx * m_parameters.imagesCount; |
| for (deUint32 imageNdx = 0; imageNdx < m_parameters.imagesCount; ++imageNdx) |
| { |
| descriptorImageInfos[descriptorNdx+imageNdx] = makeDescriptorImageInfo(*sampler, |
| imageData[imageNdx].getImageView(viewNdx), VK_IMAGE_LAYOUT_GENERAL); |
| } |
| } |
| |
| for (deUint32 ndx = 0u; ndx < descriptorSets.size(); ++ndx) |
| descriptorSets[ndx] = makeVkSharedPtr(makeDescriptorSet(vk, device, descriptorPool, descriptorSetLayout)); |
| |
| beginCommandBuffer(vk, cmdBuffer); |
| { |
| const VkImageSubresourceRange compressedRange = |
| { |
| VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask |
| 0u, //deUint32 baseMipLevel |
| imageData[0].getImageInfo(0u).mipLevels, //deUint32 levelCount |
| 0u, //deUint32 baseArrayLayer |
| imageData[0].getImageInfo(0u).arrayLayers //deUint32 layerCount |
| }; |
| const VkImageSubresourceRange uncompressedRange = |
| { |
| VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask |
| 0u, //deUint32 baseMipLevel |
| 1u, //deUint32 levelCount |
| 0u, //deUint32 baseArrayLayer |
| 1u //deUint32 layerCount |
| }; |
| |
| vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline); |
| |
| vector<VkImageMemoryBarrier> preShaderImageBarriers; |
| preShaderImageBarriers.resize(descriptorSets.size() + 1u); |
| for (deUint32 imageNdx = 0u; imageNdx < imageData[1].getImagesCount(); ++imageNdx) |
| { |
| preShaderImageBarriers[imageNdx]= makeImageMemoryBarrier( |
| VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT, |
| VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, |
| imageData[1].getImage(imageNdx), uncompressedRange); |
| } |
| |
| preShaderImageBarriers[descriptorSets.size()] = makeImageMemoryBarrier( |
| VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, |
| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, |
| imageData[0].getImage(0), compressedRange); |
| |
| vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, |
| (VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 0u, (const VkBufferMemoryBarrier*)DE_NULL, |
| static_cast<deUint32>(preShaderImageBarriers.size()), &preShaderImageBarriers[0]); |
| |
| for (deUint32 ndx = 0u; ndx <descriptorSets.size(); ++ndx) |
| { |
| descriptorSetUpdate (**descriptorSets[ndx], &descriptorImageInfos[ndx* m_parameters.imagesCount]); |
| vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &(**descriptorSets[ndx]), 0u, DE_NULL); |
| vk.cmdDispatch(cmdBuffer, imageData[1].getImageInfo(ndx).extent.width, |
| imageData[1].getImageInfo(ndx).extent.height, |
| imageData[1].getImageInfo(ndx).extent.depth); |
| } |
| } |
| endCommandBuffer(vk, cmdBuffer); |
| submitCommandsAndWait(vk, device, queue, cmdBuffer); |
| } |
| |
| bool BasicComputeTestInstance::copyResultAndCompare (const VkCommandBuffer& cmdBuffer, |
| const VkImage& uncompressed, |
| const VkDeviceSize offset, |
| const UVec3& size) |
| { |
| const DeviceInterface& vk = m_context.getDeviceInterface(); |
| const VkQueue queue = m_context.getUniversalQueue(); |
| const VkDevice device = m_context.getDevice(); |
| Allocator& allocator = m_context.getDefaultAllocator(); |
| |
| VkDeviceSize imageResultSize = getImageSizeBytes (tcu::IVec3(size.x(), size.y(), size.z()), m_parameters.formatUncompressed); |
| Buffer imageBufferResult (vk, device, allocator, |
| makeBufferCreateInfo(imageResultSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), |
| MemoryRequirement::HostVisible); |
| |
| beginCommandBuffer(vk, cmdBuffer); |
| { |
| const VkImageSubresourceRange subresourceRange = |
| { |
| VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask |
| 0u, //deUint32 baseMipLevel |
| 1u, //deUint32 levelCount |
| 0u, //deUint32 baseArrayLayer |
| 1u //deUint32 layerCount |
| }; |
| |
| 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; |
| makeExtent3D(size), // VkExtent3D imageExtent; |
| }; |
| |
| const VkImageMemoryBarrier prepareForTransferBarrier = makeImageMemoryBarrier( |
| VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, |
| VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
| uncompressed, subresourceRange); |
| |
| const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier( |
| VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, |
| imageBufferResult.get(), 0ull, imageResultSize); |
| |
| vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &prepareForTransferBarrier); |
| vk.cmdCopyImageToBuffer(cmdBuffer, uncompressed, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, imageBufferResult.get(), 1u, ©Region); |
| vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 1, ©Barrier, 0u, (const VkImageMemoryBarrier*)DE_NULL); |
| } |
| endCommandBuffer(vk, cmdBuffer); |
| submitCommandsAndWait(vk, device, queue, cmdBuffer); |
| |
| const Allocation& allocResult = imageBufferResult.getAllocation(); |
| invalidateMappedMemoryRange(vk, device, allocResult.getMemory(), allocResult.getOffset(), imageResultSize); |
| if (deMemCmp((const void *)allocResult.getHostPtr(), (const void *)&m_data[static_cast<size_t>(offset)], static_cast<size_t>(imageResultSize)) == 0ull) |
| return true; |
| return false; |
| } |
| |
| void BasicComputeTestInstance::descriptorSetUpdate (VkDescriptorSet descriptorSet, const VkDescriptorImageInfo* descriptorImageInfos) |
| { |
| const DeviceInterface& vk = m_context.getDeviceInterface(); |
| const VkDevice device = m_context.getDevice(); |
| DescriptorSetUpdateBuilder descriptorSetUpdateBuilder; |
| |
| switch(m_parameters.operation) |
| { |
| case OPERATION_IMAGE_LOAD: |
| case OPERATION_IMAGE_STORE: |
| { |
| for (deUint32 bindingNdx = 0u; bindingNdx < m_parameters.imagesCount; ++bindingNdx) |
| descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(bindingNdx), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfos[bindingNdx]); |
| |
| break; |
| } |
| |
| case OPERATION_TEXEL_FETCH: |
| case OPERATION_TEXTURE: |
| { |
| for (deUint32 bindingNdx = 0u; bindingNdx < m_parameters.imagesCount; ++bindingNdx) |
| { |
| descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(bindingNdx), |
| bindingNdx == 0u ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfos[bindingNdx]); |
| } |
| |
| break; |
| } |
| |
| default: |
| DE_ASSERT(false); |
| } |
| descriptorSetUpdateBuilder.update(vk, device); |
| } |
| |
| void BasicComputeTestInstance::createImageInfos (ImageData& imageData, const vector<UVec3>& mipMapSizes, const bool isCompressed) |
| { |
| const VkImageType imageType = mapImageType(m_parameters.imageType); |
| |
| if (isCompressed) |
| { |
| const VkExtent3D extentCompressed = makeExtent3D(getLayerSize(m_parameters.imageType, m_parameters.size)); |
| const VkImageCreateInfo compressedInfo = |
| { |
| 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_KHR | |
| VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR, // VkImageCreateFlags flags; |
| imageType, // VkImageType imageType; |
| m_parameters.formatCompressed, // VkFormat format; |
| extentCompressed, // VkExtent3D extent; |
| static_cast<deUint32>(mipMapSizes.size()), // deUint32 mipLevels; |
| getLayerCount(), // 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; |
| }; |
| imageData.addImageInfo(compressedInfo); |
| } |
| else |
| { |
| for (size_t mipNdx = 0ull; mipNdx < mipMapSizes.size(); ++mipNdx) |
| for (size_t layerNdx = 0ull; layerNdx < getLayerCount(); ++layerNdx) |
| { |
| const VkExtent3D extentUncompressed = m_parameters.useMipmaps ? |
| makeExtent3D(getCompressedImageResolutionInBlocks(m_parameters.formatCompressed, mipMapSizes[mipNdx])) : |
| makeExtent3D(getCompressedImageResolutionInBlocks(m_parameters.formatCompressed, m_parameters.size)); |
| const VkImageCreateInfo uncompressedInfo = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkImageCreateFlags flags; |
| imageType, // VkImageType imageType; |
| m_parameters.formatUncompressed, // VkFormat format; |
| extentUncompressed, // VkExtent3D extent; |
| 1u, // deUint32 mipLevels; |
| 1u, // deUint32 arrayLayers; |
| VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; |
| VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; |
| m_parameters.uncompressedImageUsage | |
| VK_IMAGE_USAGE_SAMPLED_BIT, // VkImageUsageFlags usage; |
| VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; |
| 0u, // deUint32 queueFamilyIndexCount; |
| DE_NULL, // const deUint32* pQueueFamilyIndices; |
| VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; |
| }; |
| imageData.addImageInfo(uncompressedInfo); |
| } |
| } |
| } |
| |
| bool BasicComputeTestInstance::decompressImage (const VkCommandBuffer& cmdBuffer, |
| vector<ImageData>& imageData, |
| const vector<UVec3>& mipMapSizes) |
| { |
| const DeviceInterface& vk = m_context.getDeviceInterface(); |
| const VkDevice device = m_context.getDevice(); |
| const VkQueue queue = m_context.getUniversalQueue(); |
| Allocator& allocator = m_context.getDefaultAllocator(); |
| const Unique<VkShaderModule> shaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("decompress"), 0)); |
| const VkImage& compressed = imageData[0].getImage(0); |
| |
| for (deUint32 ndx = 0u; ndx < imageData.size(); ndx++) |
| imageData[ndx].resetViews(); |
| |
| for (deUint32 mipNdx = 0u; mipNdx < mipMapSizes.size(); ++mipNdx) |
| for (deUint32 layerNdx = 0u; layerNdx < getLayerCount(); ++layerNdx) |
| { |
| const bool layoutShaderReadOnly = (layerNdx % 2u) == 1; |
| const deUint32 imageNdx = layerNdx + mipNdx * getLayerCount(); |
| const VkExtent3D extentCompressed = makeExtent3D(mipMapSizes[mipNdx]); |
| const VkImage& uncompressed = imageData[m_parameters.imagesCount -1].getImage(imageNdx); |
| const VkExtent3D extentUncompressed = imageData[m_parameters.imagesCount -1].getImageInfo(imageNdx).extent; |
| const VkDeviceSize bufferSizeComp = getCompressedImageSizeInBytes(m_parameters.formatCompressed, mipMapSizes[mipNdx]); |
| |
| const VkImageCreateInfo decompressedImageInfo = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkImageCreateFlags flags; |
| VK_IMAGE_TYPE_2D, // VkImageType imageType; |
| VK_FORMAT_R8G8B8A8_UNORM, // 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; |
| }; |
| |
| const VkImageCreateInfo compressedImageInfo = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkImageCreateFlags flags; |
| VK_IMAGE_TYPE_2D, // VkImageType imageType; |
| m_parameters.formatCompressed, // 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 VkImageUsageFlags compressedViewUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; |
| const VkImageViewUsageCreateInfoKHR compressedViewUsageCI = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, //VkStructureType sType; |
| DE_NULL, //const void* pNext; |
| compressedViewUsageFlags, //VkImageUsageFlags usage; |
| }; |
| Image resultImage (vk, device, allocator, decompressedImageInfo, MemoryRequirement::Any); |
| Image referenceImage (vk, device, allocator, decompressedImageInfo, MemoryRequirement::Any); |
| Image uncompressedImage (vk, device, allocator, compressedImageInfo, MemoryRequirement::Any); |
| Move<VkImageView> resultView = makeImageView(vk, device, resultImage.get(), mapImageViewType(m_parameters.imageType), decompressedImageInfo.format, |
| makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, decompressedImageInfo.extent.depth, 0u, decompressedImageInfo.arrayLayers)); |
| Move<VkImageView> referenceView = makeImageView(vk, device, referenceImage.get(), mapImageViewType(m_parameters.imageType), decompressedImageInfo.format, |
| makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, decompressedImageInfo.extent.depth, 0u, decompressedImageInfo.arrayLayers)); |
| Move<VkImageView> uncompressedView = makeImageView(vk, device, uncompressedImage.get(), mapImageViewType(m_parameters.imageType), m_parameters.formatCompressed, |
| makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, compressedImageInfo.extent.depth, 0u, compressedImageInfo.arrayLayers)); |
| Move<VkImageView> compressedView = makeImageView(vk, device, compressed, mapImageViewType(m_parameters.imageType), m_parameters.formatCompressed, |
| makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipNdx, 1u, layerNdx, 1u), &compressedViewUsageCI); |
| 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) |
| .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, decompressedImageInfo.arrayLayers) |
| .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, decompressedImageInfo.arrayLayers) |
| .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, decompressedImageInfo.arrayLayers) |
| .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, decompressedImageInfo.arrayLayers) |
| .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, decompressedImageInfo.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 bufferSize = getImageSizeBytes(IVec3((int)extentCompressed.width, (int)extentCompressed.height, (int)extentCompressed.depth), VK_FORMAT_R8G8B8A8_UNORM); |
| Buffer resultBuffer (vk, device, allocator, |
| makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible); |
| Buffer referenceBuffer (vk, device, allocator, |
| makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible); |
| Buffer transferBuffer (vk, device, allocator, |
| makeBufferCreateInfo(bufferSizeComp, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible); |
| Move<VkSampler> sampler; |
| { |
| 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, *uncompressedView, layoutShaderReadOnly ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL), |
| makeDescriptorImageInfo(*sampler, *compressedView, layoutShaderReadOnly ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL), |
| makeDescriptorImageInfo(DE_NULL, *resultView, VK_IMAGE_LAYOUT_GENERAL), |
| makeDescriptorImageInfo(DE_NULL, *referenceView, 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]) |
| .writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(3u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfos[3]) |
| .update(vk, device); |
| |
| |
| beginCommandBuffer(vk, cmdBuffer); |
| { |
| const VkImageSubresourceRange subresourceRange = |
| { |
| VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask |
| 0u, //deUint32 baseMipLevel |
| 1u, //deUint32 levelCount |
| 0u, //deUint32 baseArrayLayer |
| 1u //deUint32 layerCount |
| }; |
| |
| const VkImageSubresourceRange subresourceRangeComp = |
| { |
| VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask |
| mipNdx, //deUint32 baseMipLevel |
| 1u, //deUint32 levelCount |
| layerNdx, //deUint32 baseArrayLayer |
| 1u //deUint32 layerCount |
| }; |
| |
| 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; |
| decompressedImageInfo.extent, // VkExtent3D imageExtent; |
| }; |
| |
| const VkBufferImageCopy compressedCopyRegion = |
| { |
| 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; |
| extentUncompressed, // VkExtent3D imageExtent; |
| }; |
| |
| { |
| |
| const VkBufferMemoryBarrier preCopyBufferBarriers = makeBufferMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, |
| transferBuffer.get(), 0ull, bufferSizeComp); |
| |
| vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, |
| (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &preCopyBufferBarriers, 0u, (const VkImageMemoryBarrier*)DE_NULL); |
| } |
| |
| vk.cmdCopyImageToBuffer(cmdBuffer, uncompressed, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, transferBuffer.get(), 1u, &compressedCopyRegion); |
| |
| { |
| const VkBufferMemoryBarrier postCopyBufferBarriers = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, |
| transferBuffer.get(), 0ull, bufferSizeComp); |
| |
| const VkImageMemoryBarrier preCopyImageBarriers = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, |
| VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, uncompressedImage.get(), subresourceRange); |
| |
| vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, |
| (VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 1u, &postCopyBufferBarriers, 1u, &preCopyImageBarriers); |
| } |
| |
| vk.cmdCopyBufferToImage(cmdBuffer, transferBuffer.get(), uncompressedImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region); |
| |
| 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, layoutShaderReadOnly ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL, |
| uncompressedImage.get(), subresourceRange), |
| |
| makeImageMemoryBarrier(0, VK_ACCESS_SHADER_READ_BIT, |
| VK_IMAGE_LAYOUT_GENERAL, layoutShaderReadOnly ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL, |
| compressed, subresourceRangeComp), |
| |
| makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_WRITE_BIT, |
| VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, |
| resultImage.get(), subresourceRange), |
| |
| makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_WRITE_BIT, |
| VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, |
| referenceImage.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), |
| |
| makeImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, |
| VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
| referenceImage.get(), subresourceRange) |
| }; |
| |
| const VkBufferMemoryBarrier preCopyBufferBarrier[] = |
| { |
| makeBufferMemoryBarrier( 0, VK_BUFFER_USAGE_TRANSFER_DST_BIT, |
| resultBuffer.get(), 0ull, bufferSize), |
| |
| makeBufferMemoryBarrier( 0, VK_BUFFER_USAGE_TRANSFER_DST_BIT, |
| referenceBuffer.get(), 0ull, bufferSize), |
| }; |
| |
| vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, |
| (VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(preCopyBufferBarrier), preCopyBufferBarrier, |
| DE_LENGTH_OF_ARRAY(postShaderImageBarriers), postShaderImageBarriers); |
| } |
| vk.cmdCopyImageToBuffer(cmdBuffer, resultImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, resultBuffer.get(), 1u, ©Region); |
| vk.cmdCopyImageToBuffer(cmdBuffer, referenceImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, referenceBuffer.get(), 1u, ©Region); |
| } |
| endCommandBuffer(vk, cmdBuffer); |
| submitCommandsAndWait(vk, device, queue, cmdBuffer); |
| |
| const Allocation& resultAlloc = resultBuffer.getAllocation(); |
| const Allocation& referenceAlloc = referenceBuffer.getAllocation(); |
| invalidateMappedMemoryRange(vk, device, resultAlloc.getMemory(), resultAlloc.getOffset(), bufferSize); |
| invalidateMappedMemoryRange(vk, device, referenceAlloc.getMemory(), referenceAlloc.getOffset(), bufferSize); |
| |
| if (deMemCmp(resultAlloc.getHostPtr(), referenceAlloc.getHostPtr(), (size_t)bufferSize) != 0) |
| { |
| ConstPixelBufferAccess resultPixels (mapVkFormat(decompressedImageInfo.format), decompressedImageInfo.extent.width, decompressedImageInfo.extent.height, decompressedImageInfo.extent.depth, resultAlloc.getHostPtr()); |
| ConstPixelBufferAccess referencePixels (mapVkFormat(decompressedImageInfo.format), decompressedImageInfo.extent.width, decompressedImageInfo.extent.height, decompressedImageInfo.extent.depth, referenceAlloc.getHostPtr()); |
| |
| if(!fuzzyCompare(m_context.getTestContext().getLog(), "Image Comparison", "Image Comparison", resultPixels, referencePixels, 0.001f, tcu::COMPARE_LOG_EVERYTHING)) |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| class ImageStoreComputeTestInstance : public BasicComputeTestInstance |
| { |
| public: |
| ImageStoreComputeTestInstance (Context& context, |
| const TestParameters& parameters); |
| protected: |
| virtual void executeShader (const VkCommandBuffer& cmdBuffer, |
| const VkDescriptorSetLayout& descriptorSetLayout, |
| const VkDescriptorPool& descriptorPool, |
| vector<ImageData>& imageData); |
| private: |
| }; |
| |
| ImageStoreComputeTestInstance::ImageStoreComputeTestInstance (Context& context, const TestParameters& parameters) |
| :BasicComputeTestInstance (context, parameters) |
| { |
| } |
| |
| void ImageStoreComputeTestInstance::executeShader (const VkCommandBuffer& cmdBuffer, |
| const VkDescriptorSetLayout& descriptorSetLayout, |
| const VkDescriptorPool& descriptorPool, |
| vector<ImageData>& imageData) |
| { |
| const DeviceInterface& vk = m_context.getDeviceInterface(); |
| const VkDevice device = m_context.getDevice(); |
| const VkQueue queue = m_context.getUniversalQueue(); |
| const Unique<VkShaderModule> shaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0)); |
| vector<SharedVkDescriptorSet> descriptorSets (imageData[0].getImageViewCount()); |
| const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, descriptorSetLayout)); |
| const Unique<VkPipeline> pipeline (makeComputePipeline(vk, device, *pipelineLayout, *shaderModule)); |
| Move<VkSampler> sampler; |
| { |
| 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; |
| 0.0f, //float maxLod; |
| VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, //VkBorderColor borderColor; |
| VK_TRUE, //VkBool32 unnormalizedCoordinates; |
| }; |
| sampler = createSampler(vk, device, &createInfo); |
| } |
| |
| vector<VkDescriptorImageInfo> descriptorImageInfos (descriptorSets.size() * m_parameters.imagesCount); |
| for (deUint32 viewNdx = 0u; viewNdx < descriptorSets.size(); ++viewNdx) |
| { |
| const deUint32 descriptorNdx = viewNdx * m_parameters.imagesCount; |
| for (deUint32 imageNdx = 0u; imageNdx < m_parameters.imagesCount; ++imageNdx) |
| { |
| descriptorImageInfos[descriptorNdx+imageNdx] = makeDescriptorImageInfo(*sampler, |
| imageData[imageNdx].getImageView(viewNdx), VK_IMAGE_LAYOUT_GENERAL); |
| } |
| } |
| |
| for (deUint32 ndx = 0u; ndx < descriptorSets.size(); ++ndx) |
| descriptorSets[ndx] = makeVkSharedPtr(makeDescriptorSet(vk, device, descriptorPool, descriptorSetLayout)); |
| |
| beginCommandBuffer(vk, cmdBuffer); |
| { |
| const VkImageSubresourceRange compressedRange = |
| { |
| VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask |
| 0u, //deUint32 baseMipLevel |
| imageData[0].getImageInfo(0).mipLevels, //deUint32 levelCount |
| 0u, //deUint32 baseArrayLayer |
| imageData[0].getImageInfo(0).arrayLayers //deUint32 layerCount |
| }; |
| |
| const VkImageSubresourceRange uncompressedRange = |
| { |
| VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask |
| 0u, //deUint32 baseMipLevel |
| 1u, //deUint32 levelCount |
| 0u, //deUint32 baseArrayLayer |
| 1u //deUint32 layerCount |
| }; |
| |
| vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline); |
| |
| vector<VkImageMemoryBarrier> preShaderImageBarriers (descriptorSets.size() * 2u + 1u); |
| for (deUint32 imageNdx = 0u; imageNdx < imageData[1].getImagesCount(); ++imageNdx) |
| { |
| preShaderImageBarriers[imageNdx] = makeImageMemoryBarrier( |
| VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT, |
| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, |
| imageData[1].getImage(imageNdx), uncompressedRange); |
| |
| preShaderImageBarriers[imageNdx + imageData[1].getImagesCount()] = makeImageMemoryBarrier( |
| VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT, |
| VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, |
| imageData[2].getImage(imageNdx), uncompressedRange); |
| } |
| |
| preShaderImageBarriers[preShaderImageBarriers.size()-1] = makeImageMemoryBarrier( |
| VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, |
| VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, |
| imageData[0].getImage(0u), compressedRange); |
| |
| vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, |
| (VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 0u, (const VkBufferMemoryBarrier*)DE_NULL, |
| static_cast<deUint32>(preShaderImageBarriers.size()), &preShaderImageBarriers[0]); |
| |
| for (deUint32 ndx = 0u; ndx <descriptorSets.size(); ++ndx) |
| { |
| descriptorSetUpdate (**descriptorSets[ndx], &descriptorImageInfos[ndx* m_parameters.imagesCount]); |
| vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &(**descriptorSets[ndx]), 0u, DE_NULL); |
| vk.cmdDispatch(cmdBuffer, imageData[1].getImageInfo(ndx).extent.width, |
| imageData[1].getImageInfo(ndx).extent.height, |
| imageData[1].getImageInfo(ndx).extent.depth); |
| } |
| } |
| endCommandBuffer(vk, cmdBuffer); |
| submitCommandsAndWait(vk, device, queue, cmdBuffer); |
| } |
| |
| class GraphicsAttachmentsTestInstance : public BasicTranscodingTestInstance |
| { |
| public: |
| GraphicsAttachmentsTestInstance (Context& context, const TestParameters& parameters); |
| virtual TestStatus iterate (void); |
| |
| protected: |
| virtual bool isWriteToCompressedOperation (); |
| VkImageCreateInfo makeCreateImageInfo (const VkFormat format, |
| const ImageType type, |
| const UVec3& size, |
| const VkImageUsageFlags usageFlags, |
| const VkImageCreateFlags* createFlags, |
| const deUint32 levels, |
| const deUint32 layers); |
| VkDeviceSize getCompressedImageData (const VkFormat format, |
| const UVec3& size, |
| std::vector<deUint8>& data, |
| const deUint32 layer, |
| const deUint32 level); |
| VkDeviceSize getUncompressedImageData (const VkFormat format, |
| const UVec3& size, |
| std::vector<deUint8>& data, |
| const deUint32 layer, |
| const deUint32 level); |
| virtual void prepareData (); |
| virtual void prepareVertexBuffer (); |
| virtual void transcodeRead (); |
| virtual void transcodeWrite (); |
| bool verifyDecompression (const std::vector<deUint8>& refCompressedData, |
| const de::MovePtr<Image>& resCompressedImage, |
| const deUint32 layer, |
| const deUint32 level, |
| const UVec3& mipmapDims); |
| |
| typedef std::vector<deUint8> RawDataVector; |
| typedef SharedPtr<RawDataVector> RawDataPtr; |
| typedef std::vector<RawDataPtr> LevelData; |
| typedef std::vector<LevelData> FullImageData; |
| |
| FullImageData m_srcData; |
| FullImageData m_dstData; |
| |
| typedef SharedPtr<Image> ImagePtr; |
| typedef std::vector<ImagePtr> LevelImages; |
| typedef std::vector<LevelImages> ImagesArray; |
| |
| ImagesArray m_uncompressedImages; |
| MovePtr<Image> m_compressedImage; |
| |
| VkImageViewUsageCreateInfoKHR m_imageViewUsageKHR; |
| VkImageViewUsageCreateInfoKHR* m_srcImageViewUsageKHR; |
| VkImageViewUsageCreateInfoKHR* m_dstImageViewUsageKHR; |
| std::vector<tcu::UVec3> m_compressedImageResVec; |
| std::vector<tcu::UVec3> m_uncompressedImageResVec; |
| VkFormat m_srcFormat; |
| VkFormat m_dstFormat; |
| VkImageUsageFlags m_srcImageUsageFlags; |
| VkImageUsageFlags m_dstImageUsageFlags; |
| std::vector<tcu::UVec3> m_srcImageResolutions; |
| std::vector<tcu::UVec3> m_dstImageResolutions; |
| |
| MovePtr<Buffer> m_vertexBuffer; |
| deUint32 m_vertexCount; |
| VkDeviceSize m_vertexBufferOffset; |
| }; |
| |
| GraphicsAttachmentsTestInstance::GraphicsAttachmentsTestInstance (Context& context, const TestParameters& parameters) |
| : BasicTranscodingTestInstance(context, parameters) |
| , m_srcData() |
| , m_dstData() |
| , m_uncompressedImages() |
| , m_compressedImage() |
| , m_imageViewUsageKHR() |
| , m_srcImageViewUsageKHR() |
| , m_dstImageViewUsageKHR() |
| , m_compressedImageResVec() |
| , m_uncompressedImageResVec() |
| , m_srcFormat() |
| , m_dstFormat() |
| , m_srcImageUsageFlags() |
| , m_dstImageUsageFlags() |
| , m_srcImageResolutions() |
| , m_dstImageResolutions() |
| , m_vertexBuffer() |
| , m_vertexCount(0u) |
| , m_vertexBufferOffset(0ull) |
| { |
| } |
| |
| TestStatus GraphicsAttachmentsTestInstance::iterate (void) |
| { |
| prepareData(); |
| prepareVertexBuffer(); |
| |
| for (deUint32 levelNdx = 0; levelNdx < getLevelCount(); ++levelNdx) |
| for (deUint32 layerNdx = 0; layerNdx < getLayerCount(); ++layerNdx) |
| DE_ASSERT(m_srcData[levelNdx][layerNdx]->size() == m_dstData[levelNdx][layerNdx]->size()); |
| |
| if (isWriteToCompressedOperation()) |
| transcodeWrite(); |
| else |
| transcodeRead(); |
| |
| for (deUint32 levelNdx = 0; levelNdx < getLevelCount(); ++levelNdx) |
| for (deUint32 layerNdx = 0; layerNdx < getLayerCount(); ++layerNdx) |
| if (isWriteToCompressedOperation()) |
| { |
| if (!verifyDecompression(*m_srcData[levelNdx][layerNdx], m_compressedImage, levelNdx, layerNdx, m_compressedImageResVec[levelNdx])) |
| return TestStatus::fail("Images difference detected"); |
| } |
| else |
| { |
| if (!verifyDecompression(*m_dstData[levelNdx][layerNdx], m_compressedImage, levelNdx, layerNdx, m_compressedImageResVec[levelNdx])) |
| return TestStatus::fail("Images difference detected"); |
| } |
| |
| return TestStatus::pass("Pass"); |
| } |
| |
| void GraphicsAttachmentsTestInstance::prepareData () |
| { |
| VkImageViewUsageCreateInfoKHR* imageViewUsageKHRNull = (VkImageViewUsageCreateInfoKHR*)DE_NULL; |
| |
| m_imageViewUsageKHR = makeImageViewUsageCreateInfo(m_parameters.compressedImageViewUsage); |
| |
| m_srcImageViewUsageKHR = isWriteToCompressedOperation() ? imageViewUsageKHRNull : &m_imageViewUsageKHR; |
| m_dstImageViewUsageKHR = isWriteToCompressedOperation() ? &m_imageViewUsageKHR : imageViewUsageKHRNull; |
| |
| m_srcFormat = isWriteToCompressedOperation() ? m_parameters.formatUncompressed : m_parameters.formatCompressed; |
| m_dstFormat = isWriteToCompressedOperation() ? m_parameters.formatCompressed : m_parameters.formatUncompressed; |
| |
| m_srcImageUsageFlags = isWriteToCompressedOperation() ? m_parameters.uncompressedImageUsage : m_parameters.compressedImageUsage; |
| m_dstImageUsageFlags = isWriteToCompressedOperation() ? m_parameters.compressedImageUsage : m_parameters.uncompressedImageUsage; |
| |
| m_compressedImageResVec = getMipLevelSizes(getLayerDims()); |
| m_uncompressedImageResVec = getCompressedMipLevelSizes(m_parameters.formatCompressed, m_compressedImageResVec); |
| |
| m_srcImageResolutions = isWriteToCompressedOperation() ? m_uncompressedImageResVec : m_compressedImageResVec; |
| m_dstImageResolutions = isWriteToCompressedOperation() ? m_compressedImageResVec : m_uncompressedImageResVec; |
| |
| m_srcData.resize(getLevelCount()); |
| m_dstData.resize(getLevelCount()); |
| m_uncompressedImages.resize(getLevelCount()); |
| |
| for (deUint32 levelNdx = 0; levelNdx < getLevelCount(); ++levelNdx) |
| { |
| m_srcData[levelNdx].resize(getLayerCount()); |
| m_dstData[levelNdx].resize(getLayerCount()); |
| m_uncompressedImages[levelNdx].resize(getLayerCount()); |
| |
| for (deUint32 layerNdx = 0; layerNdx < getLayerCount(); ++layerNdx) |
| { |
| m_srcData[levelNdx][layerNdx] = SharedPtr<RawDataVector>(new RawDataVector); |
| m_dstData[levelNdx][layerNdx] = SharedPtr<RawDataVector>(new RawDataVector); |
| |
| if (isWriteToCompressedOperation()) |
| { |
| getUncompressedImageData(m_srcFormat, m_srcImageResolutions[levelNdx], *m_srcData[levelNdx][layerNdx], layerNdx, levelNdx); |
| |
| m_dstData[levelNdx][layerNdx]->resize((size_t)getCompressedImageSizeInBytes(m_dstFormat, m_dstImageResolutions[levelNdx])); |
| } |
| else |
| { |
| getCompressedImageData(m_srcFormat, m_srcImageResolutions[levelNdx], *m_srcData[levelNdx][layerNdx], layerNdx, levelNdx); |
| |
| m_dstData[levelNdx][layerNdx]->resize((size_t)getUncompressedImageSizeInBytes(m_dstFormat, m_dstImageResolutions[levelNdx])); |
| } |
| |
| DE_ASSERT(m_srcData[levelNdx][layerNdx]->size() == m_dstData[levelNdx][layerNdx]->size()); |
| } |
| } |
| } |
| |
| void GraphicsAttachmentsTestInstance::prepareVertexBuffer () |
| { |
| const DeviceInterface& vk = m_context.getDeviceInterface(); |
| const VkDevice device = m_context.getDevice(); |
| Allocator& allocator = m_context.getDefaultAllocator(); |
| |
| const std::vector<tcu::Vec4> vertexArray = createFullscreenQuad(); |
| const size_t vertexBufferSizeInBytes = vertexArray.size() * sizeof(vertexArray[0]); |
| |
| m_vertexCount = static_cast<deUint32>(vertexArray.size()); |
| m_vertexBuffer = MovePtr<Buffer>(new Buffer(vk, device, allocator, makeBufferCreateInfo(vertexBufferSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible)); |
| |
| // Upload vertex data |
| const Allocation& vertexBufferAlloc = m_vertexBuffer->getAllocation(); |
| deMemcpy(vertexBufferAlloc.getHostPtr(), &vertexArray[0], vertexBufferSizeInBytes); |
| flushMappedMemoryRange(vk, device, vertexBufferAlloc.getMemory(), vertexBufferAlloc.getOffset(), vertexBufferSizeInBytes); |
| } |
| |
| void GraphicsAttachmentsTestInstance::transcodeRead () |
| { |
| const DeviceInterface& vk = m_context.getDeviceInterface(); |
| const VkDevice device = m_context.getDevice(); |
| const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); |
| const VkQueue queue = m_context.getUniversalQueue(); |
| Allocator& allocator = m_context.getDefaultAllocator(); |
| |
| const VkImageCreateFlags* imgCreateFlagsOverride = DE_NULL; |
| |
| const VkImageCreateInfo srcImageCreateInfo = makeCreateImageInfo(m_srcFormat, m_parameters.imageType, m_srcImageResolutions[0], m_srcImageUsageFlags, imgCreateFlagsOverride, getLevelCount(), getLayerCount()); |
| MovePtr<Image> srcImage (new Image(vk, device, allocator, srcImageCreateInfo, MemoryRequirement::Any)); |
| |
| const Unique<VkShaderModule> vertShaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0)); |
| const Unique<VkShaderModule> fragShaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0)); |
| |
| const Unique<VkRenderPass> renderPass (makeRenderPass(vk, device, m_parameters.formatUncompressed, m_parameters.formatUncompressed)); |
| |
| const Move<VkDescriptorSetLayout> descriptorSetLayout (DescriptorSetLayoutBuilder() |
| .addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT) |
| .build(vk, device)); |
| const Move<VkDescriptorPool> descriptorPool (DescriptorPoolBuilder() |
| .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) |
| .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); |
| const Move<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout)); |
| |
| const VkExtent2D renderSizeDummy (makeExtent2D(1u, 1u)); |
| const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout)); |
| const Unique<VkPipeline> pipeline (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertShaderModule, *fragShaderModule, renderSizeDummy, 1u, true)); |
| |
| 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)); |
| |
| for (deUint32 levelNdx = 0; levelNdx < getLevelCount(); ++levelNdx) |
| { |
| const UVec3& uncompressedImageRes = m_uncompressedImageResVec[levelNdx]; |
| const UVec3& srcImageResolution = m_srcImageResolutions[levelNdx]; |
| const UVec3& dstImageResolution = m_dstImageResolutions[levelNdx]; |
| const size_t srcImageSizeInBytes = m_srcData[levelNdx][0]->size(); |
| const size_t dstImageSizeInBytes = m_dstData[levelNdx][0]->size(); |
| const UVec3 srcImageResBlocked = getCompressedImageResolutionBlockCeil(m_parameters.formatCompressed, srcImageResolution); |
| |
| const VkImageCreateInfo dstImageCreateInfo = makeCreateImageInfo(m_dstFormat, m_parameters.imageType, dstImageResolution, m_dstImageUsageFlags, imgCreateFlagsOverride, SINGLE_LEVEL, SINGLE_LAYER); |
| |
| const VkBufferCreateInfo srcImageBufferInfo = makeBufferCreateInfo(srcImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); |
| const MovePtr<Buffer> srcImageBuffer = MovePtr<Buffer>(new Buffer(vk, device, allocator, srcImageBufferInfo, MemoryRequirement::HostVisible)); |
| |
| const VkBufferCreateInfo dstImageBufferInfo = makeBufferCreateInfo(dstImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT); |
| MovePtr<Buffer> dstImageBuffer = MovePtr<Buffer>(new Buffer(vk, device, allocator, dstImageBufferInfo, MemoryRequirement::HostVisible)); |
| |
| const VkExtent2D renderSize (makeExtent2D(uncompressedImageRes.x(), uncompressedImageRes.y())); |
| const VkViewport viewport = makeViewport(0.0f, 0.0f, static_cast<float>(renderSize.width), static_cast<float>(renderSize.height), 0.0f, 1.0f); |
| const VkRect2D scissor = makeScissor(renderSize.width, renderSize.height); |
| |
| for (deUint32 layerNdx = 0; layerNdx < getLayerCount(); ++layerNdx) |
| { |
| const VkImageSubresourceRange srcSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, levelNdx, SINGLE_LEVEL, layerNdx, SINGLE_LAYER); |
| const VkImageSubresourceRange dstSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, SINGLE_LEVEL, 0u, SINGLE_LAYER); |
| |
| Move<VkImageView> srcImageView (makeImageView(vk, device, srcImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed, srcSubresourceRange, m_srcImageViewUsageKHR)); |
| |
| de::MovePtr<Image> dstImage (new Image(vk, device, allocator, dstImageCreateInfo, MemoryRequirement::Any)); |
| Move<VkImageView> dstImageView (makeImageView(vk, device, dstImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed, dstSubresourceRange, m_dstImageViewUsageKHR)); |
| |
| const VkBufferImageCopy srcCopyRegion = makeBufferImageCopy(srcImageResolution.x(), srcImageResolution.y(), levelNdx, layerNdx, srcImageResBlocked.x(), srcImageResBlocked.y()); |
| const VkBufferMemoryBarrier srcCopyBufferBarrierPre = makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, srcImageBuffer->get(), 0ull, srcImageSizeInBytes); |
| const VkImageMemoryBarrier srcCopyImageBarrierPre = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, srcImage->get(), srcSubresourceRange); |
| const VkImageMemoryBarrier srcCopyImageBarrierPost = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, srcImage->get(), srcSubresourceRange); |
| const VkBufferImageCopy dstCopyRegion = makeBufferImageCopy(dstImageResolution.x(), dstImageResolution.y()); |
| const VkImageMemoryBarrier dstInitImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, dstImage->get(), dstSubresourceRange); |
| |
| const VkImageView attachmentBindInfos[] = { *srcImageView, *dstImageView }; |
| const VkExtent2D framebufferSize (makeExtent2D(dstImageResolution[0], dstImageResolution[1])); |
| const Move<VkFramebuffer> framebuffer (makeFramebuffer(vk, device, *renderPass, DE_LENGTH_OF_ARRAY(attachmentBindInfos), attachmentBindInfos, framebufferSize, SINGLE_LAYER)); |
| |
| // Upload source image data |
| const Allocation& alloc = srcImageBuffer->getAllocation(); |
| deMemcpy(alloc.getHostPtr(), &m_srcData[levelNdx][layerNdx]->at(0), srcImageSizeInBytes); |
| flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), srcImageSizeInBytes); |
| |
| beginCommandBuffer(vk, *cmdBuffer); |
| vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); |
| |
| // Copy buffer to image |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &srcCopyBufferBarrierPre, 1u, &srcCopyImageBarrierPre); |
| vk.cmdCopyBufferToImage(*cmdBuffer, srcImageBuffer->get(), srcImage->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &srcCopyRegion); |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &srcCopyImageBarrierPost); |
| |
| // Define destination image layout |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &dstInitImageBarrier); |
| |
| beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize); |
| |
| const VkDescriptorImageInfo descriptorSrcImageInfo(makeDescriptorImageInfo(DE_NULL, *srcImageView, VK_IMAGE_LAYOUT_GENERAL)); |
| DescriptorSetUpdateBuilder() |
| .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descriptorSrcImageInfo) |
| .update(vk, device); |
| |
| vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL); |
| vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &m_vertexBuffer->get(), &m_vertexBufferOffset); |
| |
| vk.cmdSetViewport(*cmdBuffer, 0u, 1u, &viewport); |
| vk.cmdSetScissor(*cmdBuffer, 0u, 1u, &scissor); |
| |
| vk.cmdDraw(*cmdBuffer, (deUint32)m_vertexCount, 1, 0, 0); |
| |
| vk.cmdEndRenderPass(*cmdBuffer); |
| |
| const VkImageMemoryBarrier prepareForTransferBarrier = makeImageMemoryBarrier( |
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, |
| VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, |
| dstImage->get(), dstSubresourceRange); |
| |
| const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier( |
| VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, |
| dstImageBuffer->get(), 0ull, dstImageSizeInBytes); |
| |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &prepareForTransferBarrier); |
| vk.cmdCopyImageToBuffer(*cmdBuffer, dstImage->get(), VK_IMAGE_LAYOUT_GENERAL, dstImageBuffer->get(), 1u, &dstCopyRegion); |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, ©Barrier, 0, (const VkImageMemoryBarrier*)DE_NULL); |
| |
| endCommandBuffer(vk, *cmdBuffer); |
| |
| submitCommandsAndWait(vk, device, queue, *cmdBuffer); |
| |
| const Allocation& dstImageBufferAlloc = dstImageBuffer->getAllocation(); |
| invalidateMappedMemoryRange(vk, device, dstImageBufferAlloc.getMemory(), dstImageBufferAlloc.getOffset(), dstImageSizeInBytes); |
| deMemcpy(&m_dstData[levelNdx][layerNdx]->at(0), dstImageBufferAlloc.getHostPtr(), dstImageSizeInBytes); |
| } |
| } |
| |
| m_compressedImage = srcImage; |
| } |
| |
| void GraphicsAttachmentsTestInstance::transcodeWrite () |
| { |
| const DeviceInterface& vk = m_context.getDeviceInterface(); |
| const VkDevice device = m_context.getDevice(); |
| const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); |
| const VkQueue queue = m_context.getUniversalQueue(); |
| Allocator& allocator = m_context.getDefaultAllocator(); |
| |
| const VkImageCreateFlags* imgCreateFlagsOverride = DE_NULL; |
| |
| const VkImageCreateInfo dstImageCreateInfo = makeCreateImageInfo(m_dstFormat, m_parameters.imageType, m_dstImageResolutions[0], m_dstImageUsageFlags, imgCreateFlagsOverride, getLevelCount(), getLayerCount()); |
| MovePtr<Image> dstImage (new Image(vk, device, allocator, dstImageCreateInfo, MemoryRequirement::Any)); |
| |
| const Unique<VkShaderModule> vertShaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0)); |
| const Unique<VkShaderModule> fragShaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0)); |
| |
| const Unique<VkRenderPass> renderPass (makeRenderPass(vk, device, m_parameters.formatUncompressed, m_parameters.formatUncompressed)); |
| |
| const Move<VkDescriptorSetLayout> descriptorSetLayout (DescriptorSetLayoutBuilder() |
| .addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT) |
| .build(vk, device)); |
| const Move<VkDescriptorPool> descriptorPool (DescriptorPoolBuilder() |
| .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) |
| .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); |
| const Move<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout)); |
| |
| const VkExtent2D renderSizeDummy (makeExtent2D(1u, 1u)); |
| const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout)); |
| const Unique<VkPipeline> pipeline (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertShaderModule, *fragShaderModule, renderSizeDummy, 1u, true)); |
| |
| 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)); |
| |
| for (deUint32 levelNdx = 0; levelNdx < getLevelCount(); ++levelNdx) |
| { |
| const UVec3& uncompressedImageRes = m_uncompressedImageResVec[levelNdx]; |
| const UVec3& srcImageResolution = m_srcImageResolutions[levelNdx]; |
| const UVec3& dstImageResolution = m_dstImageResolutions[levelNdx]; |
| const UVec3 dstImageResBlocked = getCompressedImageResolutionBlockCeil(m_parameters.formatCompressed, dstImageResolution); |
| const size_t srcImageSizeInBytes = m_srcData[levelNdx][0]->size(); |
| const size_t dstImageSizeInBytes = m_dstData[levelNdx][0]->size(); |
| |
| const VkImageCreateInfo srcImageCreateInfo = makeCreateImageInfo(m_srcFormat, m_parameters.imageType, srcImageResolution, m_srcImageUsageFlags, imgCreateFlagsOverride, SINGLE_LEVEL, SINGLE_LAYER); |
| |
| const VkExtent2D renderSize (makeExtent2D(uncompressedImageRes.x(), uncompressedImageRes.y())); |
| const VkViewport viewport = makeViewport(0.0f, 0.0f, static_cast<float>(renderSize.width), static_cast<float>(renderSize.height), 0.0f, 1.0f); |
| const VkRect2D scissor = makeScissor(renderSize.width, renderSize.height); |
| |
| for (deUint32 layerNdx = 0; layerNdx < getLayerCount(); ++layerNdx) |
| { |
| const VkBufferCreateInfo srcImageBufferInfo = makeBufferCreateInfo(srcImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); |
| const MovePtr<Buffer> srcImageBuffer = MovePtr<Buffer>(new Buffer(vk, device, allocator, srcImageBufferInfo, MemoryRequirement::HostVisible)); |
| |
| const VkBufferCreateInfo dstImageBufferInfo = makeBufferCreateInfo(dstImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT); |
| MovePtr<Buffer> dstImageBuffer = MovePtr<Buffer>(new Buffer(vk, device, allocator, dstImageBufferInfo, MemoryRequirement::HostVisible)); |
| |
| const VkImageSubresourceRange srcSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, SINGLE_LEVEL, 0u, SINGLE_LAYER); |
| const VkImageSubresourceRange dstSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, levelNdx, SINGLE_LEVEL, layerNdx, SINGLE_LAYER); |
| |
| Move<VkImageView> dstImageView (makeImageView(vk, device, dstImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed, dstSubresourceRange, m_dstImageViewUsageKHR)); |
| |
| de::MovePtr<Image> srcImage (new Image(vk, device, allocator, srcImageCreateInfo, MemoryRequirement::Any)); |
| Move<VkImageView> srcImageView (makeImageView(vk, device, srcImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed, srcSubresourceRange, m_srcImageViewUsageKHR)); |
| |
| const VkBufferImageCopy srcCopyRegion = makeBufferImageCopy(srcImageResolution.x(), srcImageResolution.y(), 0u, 0u); |
| const VkBufferMemoryBarrier srcCopyBufferBarrierPre = makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, srcImageBuffer->get(), 0ull, srcImageSizeInBytes); |
| const VkImageMemoryBarrier srcCopyImageBarrierPre = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, srcImage->get(), srcSubresourceRange); |
| const VkImageMemoryBarrier srcCopyImageBarrierPost = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, srcImage->get(), srcSubresourceRange); |
| const VkBufferImageCopy dstCopyRegion = makeBufferImageCopy(dstImageResolution.x(), dstImageResolution.y(), levelNdx, layerNdx, dstImageResBlocked.x(), dstImageResBlocked.y()); |
| const VkImageMemoryBarrier dstInitImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, dstImage->get(), dstSubresourceRange); |
| |
| const VkImageView attachmentBindInfos[] = { *srcImageView, *dstImageView }; |
| const VkExtent2D framebufferSize (renderSize); |
| const Move<VkFramebuffer> framebuffer (makeFramebuffer(vk, device, *renderPass, DE_LENGTH_OF_ARRAY(attachmentBindInfos), attachmentBindInfos, framebufferSize, SINGLE_LAYER)); |
| |
| // Upload source image data |
| const Allocation& alloc = srcImageBuffer->getAllocation(); |
| deMemcpy(alloc.getHostPtr(), &m_srcData[levelNdx][layerNdx]->at(0), srcImageSizeInBytes); |
| flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), srcImageSizeInBytes); |
| |
| beginCommandBuffer(vk, *cmdBuffer); |
| vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); |
| |
| // Copy buffer to image |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &srcCopyBufferBarrierPre, 1u, &srcCopyImageBarrierPre); |
| vk.cmdCopyBufferToImage(*cmdBuffer, srcImageBuffer->get(), srcImage->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &srcCopyRegion); |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &srcCopyImageBarrierPost); |
| |
| // Define destination image layout |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &dstInitImageBarrier); |
| |
| beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize); |
| |
| const VkDescriptorImageInfo descriptorSrcImageInfo(makeDescriptorImageInfo(DE_NULL, *srcImageView, VK_IMAGE_LAYOUT_GENERAL)); |
| DescriptorSetUpdateBuilder() |
| .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descriptorSrcImageInfo) |
| .update(vk, device); |
| |
| vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL); |
| vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &m_vertexBuffer->get(), &m_vertexBufferOffset); |
| |
| vk.cmdSetViewport(*cmdBuffer, 0u, 1u, &viewport); |
| vk.cmdSetScissor(*cmdBuffer, 0u, 1u, &scissor); |
| |
| vk.cmdDraw(*cmdBuffer, (deUint32)m_vertexCount, 1, 0, 0); |
| |
| vk.cmdEndRenderPass(*cmdBuffer); |
| |
| const VkImageMemoryBarrier prepareForTransferBarrier = makeImageMemoryBarrier( |
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, |
| VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, |
| dstImage->get(), dstSubresourceRange); |
| |
| const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier( |
| VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, |
| dstImageBuffer->get(), 0ull, dstImageSizeInBytes); |
| |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &prepareForTransferBarrier); |
| vk.cmdCopyImageToBuffer(*cmdBuffer, dstImage->get(), VK_IMAGE_LAYOUT_GENERAL, dstImageBuffer->get(), 1u, &dstCopyRegion); |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, ©Barrier, 0, (const VkImageMemoryBarrier*)DE_NULL); |
| |
| endCommandBuffer(vk, *cmdBuffer); |
| |
| submitCommandsAndWait(vk, device, queue, *cmdBuffer); |
| |
| const Allocation& dstImageBufferAlloc = dstImageBuffer->getAllocation(); |
| invalidateMappedMemoryRange(vk, device, dstImageBufferAlloc.getMemory(), dstImageBufferAlloc.getOffset(), dstImageSizeInBytes); |
| deMemcpy(&m_dstData[levelNdx][layerNdx]->at(0), dstImageBufferAlloc.getHostPtr(), dstImageSizeInBytes); |
| } |
| } |
| |
| m_compressedImage = dstImage; |
| } |
| |
| bool GraphicsAttachmentsTestInstance::isWriteToCompressedOperation () |
| { |
| return (m_parameters.operation == OPERATION_ATTACHMENT_WRITE); |
| } |
| |
| VkImageCreateInfo GraphicsAttachmentsTestInstance::makeCreateImageInfo (const VkFormat format, |
| const ImageType type, |
| const UVec3& size, |
| const VkImageUsageFlags usageFlags, |
| const VkImageCreateFlags* createFlags, |
| const deUint32 levels, |
| const deUint32 layers) |
| { |
| const VkImageType imageType = mapImageType(type); |
| const VkImageCreateFlags imageCreateFlagsBase = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; |
| const VkImageCreateFlags imageCreateFlagsAddOn = isCompressedFormat(format) ? VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR : 0; |
| const VkImageCreateFlags imageCreateFlags = (createFlags != DE_NULL) ? *createFlags : (imageCreateFlagsBase | imageCreateFlagsAddOn); |
| |
| const VkImageCreateInfo createImageInfo = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| imageCreateFlags, // VkImageCreateFlags flags; |
| imageType, // VkImageType imageType; |
| format, // VkFormat format; |
| makeExtent3D(getLayerSize(type, size)), // VkExtent3D extent; |
| levels, // deUint32 mipLevels; |
| layers, // deUint32 arrayLayers; |
| VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; |
| VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; |
| usageFlags, // VkImageUsageFlags usage; |
| VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; |
| 0u, // deUint32 queueFamilyIndexCount; |
| DE_NULL, // const deUint32* pQueueFamilyIndices; |
| VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; |
| }; |
| |
| return createImageInfo; |
| } |
| |
| VkDeviceSize GraphicsAttachmentsTestInstance::getCompressedImageData (const VkFormat format, |
| const UVec3& size, |
| std::vector<deUint8>& data, |
| const deUint32 layer, |
| const deUint32 level) |
| { |
| VkDeviceSize sizeBytes = getCompressedImageSizeInBytes(format, size); |
| |
| data.resize((size_t)sizeBytes); |
| generateData(&data[0], data.size(), format, layer, level); |
| |
| return sizeBytes; |
| } |
| |
| VkDeviceSize GraphicsAttachmentsTestInstance::getUncompressedImageData (const VkFormat format, |
| const UVec3& size, |
| std::vector<deUint8>& data, |
| const deUint32 layer, |
| const deUint32 level) |
| { |
| tcu::IVec3 sizeAsIVec3 = tcu::IVec3(static_cast<int>(size[0]), static_cast<int>(size[1]), static_cast<int>(size[2])); |
| VkDeviceSize sizeBytes = getImageSizeBytes(sizeAsIVec3, format); |
| |
| data.resize((size_t)sizeBytes); |
| generateData(&data[0], data.size(), format, layer, level); |
| |
| return sizeBytes; |
| } |
| |
| bool GraphicsAttachmentsTestInstance::verifyDecompression (const std::vector<deUint8>& refCompressedData, |
| const de::MovePtr<Image>& resCompressedImage, |
| const deUint32 level, |
| const deUint32 layer, |
| const UVec3& mipmapDims) |
| { |
| const DeviceInterface& vk = m_context.getDeviceInterface(); |
| const VkDevice device = m_context.getDevice(); |
| const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); |
| const VkQueue queue = m_context.getUniversalQueue(); |
| Allocator& allocator = m_context.getDefaultAllocator(); |
| |
| const bool layoutShaderReadOnly = (layer % 2u) == 1; |
| const UVec3 mipmapDimsBlocked = getCompressedImageResolutionBlockCeil(m_parameters.formatCompressed, mipmapDims); |
| |
| const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, SINGLE_LEVEL, 0u, SINGLE_LAYER); |
| const VkImageSubresourceRange resSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, level, SINGLE_LEVEL, layer, SINGLE_LAYER); |
| |
| const VkDeviceSize dstBufferSize = getUncompressedImageSizeInBytes(m_parameters.formatForVerify, mipmapDims); |
| const VkImageUsageFlags refSrcImageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; |
| |
| const VkBufferCreateInfo refSrcImageBufferInfo (makeBufferCreateInfo(refCompressedData.size(), VK_BUFFER_USAGE_TRANSFER_SRC_BIT)); |
| const MovePtr<Buffer> refSrcImageBuffer = MovePtr<Buffer>(new Buffer(vk, device, allocator, refSrcImageBufferInfo, MemoryRequirement::HostVisible)); |
| |
| const VkImageCreateFlags refSrcImageCreateFlags = 0; |
| const VkImageCreateInfo refSrcImageCreateInfo = makeCreateImageInfo(m_parameters.formatCompressed, m_parameters.imageType, mipmapDimsBlocked, refSrcImageUsageFlags, &refSrcImageCreateFlags, SINGLE_LEVEL, SINGLE_LAYER); |
| const MovePtr<Image> refSrcImage (new Image(vk, device, allocator, refSrcImageCreateInfo, MemoryRequirement::Any)); |
| Move<VkImageView> refSrcImageView (makeImageView(vk, device, refSrcImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatCompressed, subresourceRange)); |
| |
| const VkImageUsageFlags resSrcImageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; |
| const VkImageViewUsageCreateInfoKHR resSrcImageViewUsageKHR = makeImageViewUsageCreateInfo(resSrcImageUsageFlags); |
| Move<VkImageView> resSrcImageView (makeImageView(vk, device, resCompressedImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatCompressed, resSubresourceRange, &resSrcImageViewUsageKHR)); |
| |
| const VkImageCreateFlags refDstImageCreateFlags = 0; |
| const VkImageUsageFlags refDstImageUsageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; |
| const VkImageCreateInfo refDstImageCreateInfo = makeCreateImageInfo(m_parameters.formatForVerify, m_parameters.imageType, mipmapDims, refDstImageUsageFlags, &refDstImageCreateFlags, SINGLE_LEVEL, SINGLE_LAYER); |
| const MovePtr<Image> refDstImage (new Image(vk, device, allocator, refDstImageCreateInfo, MemoryRequirement::Any)); |
| const Move<VkImageView> refDstImageView (makeImageView(vk, device, refDstImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatForVerify, subresourceRange)); |
| const VkImageMemoryBarrier refDstInitImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, refDstImage->get(), subresourceRange); |
| const VkBufferCreateInfo refDstBufferInfo (makeBufferCreateInfo(dstBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)); |
| const MovePtr<Buffer> refDstBuffer = MovePtr<Buffer>(new Buffer(vk, device, allocator, refDstBufferInfo, MemoryRequirement::HostVisible)); |
| |
| const VkImageCreateFlags resDstImageCreateFlags = 0; |
| const VkImageUsageFlags resDstImageUsageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; |
| const VkImageCreateInfo resDstImageCreateInfo = makeCreateImageInfo(m_parameters.formatForVerify, m_parameters.imageType, mipmapDims, resDstImageUsageFlags, &resDstImageCreateFlags, SINGLE_LEVEL, SINGLE_LAYER); |
| const MovePtr<Image> resDstImage (new Image(vk, device, allocator, resDstImageCreateInfo, MemoryRequirement::Any)); |
| const Move<VkImageView> resDstImageView (makeImageView(vk, device, resDstImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatForVerify, subresourceRange)); |
| const VkImageMemoryBarrier resDstInitImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, resDstImage->get(), subresourceRange); |
| const VkBufferCreateInfo resDstBufferInfo (makeBufferCreateInfo(dstBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT)); |
| const MovePtr<Buffer> resDstBuffer = MovePtr<Buffer>(new Buffer(vk, device, allocator, resDstBufferInfo, MemoryRequirement::HostVisible)); |
| |
| const Unique<VkShaderModule> vertShaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0)); |
| const Unique<VkShaderModule> fragShaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("frag_verify"), 0)); |
| |
| const Unique<VkRenderPass> renderPass (makeRenderPass(vk, device)); |
| |
| const Move<VkDescriptorSetLayout> descriptorSetLayout (DescriptorSetLayoutBuilder() |
| .addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT) |
| .addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT) |
| .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT) |
| .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT) |
| .build(vk, device)); |
| const Move<VkDescriptorPool> descriptorPool (DescriptorPoolBuilder() |
| .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) |
| .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) |
| .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) |
| .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) |
| .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); |
| const Move<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout)); |
| const VkSamplerCreateInfo refSrcSamplerInfo (makeSamplerCreateInfo()); |
| const Move<VkSampler> refSrcSampler = vk::createSampler(vk, device, &refSrcSamplerInfo); |
| const VkSamplerCreateInfo resSrcSamplerInfo (makeSamplerCreateInfo()); |
| const Move<VkSampler> resSrcSampler = vk::createSampler(vk, device, &resSrcSamplerInfo); |
| const VkDescriptorImageInfo descriptorRefSrcImage (makeDescriptorImageInfo(*refSrcSampler, *refSrcImageView, layoutShaderReadOnly ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL)); |
| const VkDescriptorImageInfo descriptorResSrcImage (makeDescriptorImageInfo(*resSrcSampler, *resSrcImageView, layoutShaderReadOnly ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL)); |
| const VkDescriptorImageInfo descriptorRefDstImage (makeDescriptorImageInfo(DE_NULL, *refDstImageView, VK_IMAGE_LAYOUT_GENERAL)); |
| const VkDescriptorImageInfo descriptorResDstImage (makeDescriptorImageInfo(DE_NULL, *resDstImageView, VK_IMAGE_LAYOUT_GENERAL)); |
| |
| const VkExtent2D renderSize (makeExtent2D(mipmapDims.x(), mipmapDims.y())); |
| const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout)); |
| const Unique<VkPipeline> pipeline (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertShaderModule, *fragShaderModule, renderSize, 0u)); |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT, queueFamilyIndex)); |
| const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); |
| |
| const VkBufferImageCopy copyBufferToImageRegion = makeBufferImageCopy(mipmapDimsBlocked.x(), mipmapDimsBlocked.y(), 0u, 0u, mipmapDimsBlocked.x(), mipmapDimsBlocked.y()); |
| const VkBufferImageCopy copyRegion = makeBufferImageCopy(mipmapDims.x(), mipmapDims.y(), 0u, 0u); |
| const VkBufferMemoryBarrier refSrcCopyBufferBarrierPre = makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, refSrcImageBuffer->get(), 0ull, refCompressedData.size()); |
| const VkImageMemoryBarrier refSrcCopyImageBarrierPre = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, refSrcImage->get(), subresourceRange); |
| const VkImageMemoryBarrier refSrcCopyImageBarrierPost = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL, layoutShaderReadOnly ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL, refSrcImage->get(), subresourceRange); |
| const VkImageMemoryBarrier resCompressedImageBarrier = makeImageMemoryBarrier(0, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL, layoutShaderReadOnly ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL, resCompressedImage->get(), resSubresourceRange); |
| |
| const Move<VkFramebuffer> framebuffer (makeFramebuffer(vk, device, *renderPass, 0, DE_NULL, renderSize, getLayerCount())); |
| |
| // Upload source image data |
| { |
| const Allocation& refSrcImageBufferAlloc = refSrcImageBuffer->getAllocation(); |
| deMemcpy(refSrcImageBufferAlloc.getHostPtr(), &refCompressedData[0], refCompressedData.size()); |
| flushMappedMemoryRange(vk, device, refSrcImageBufferAlloc.getMemory(), refSrcImageBufferAlloc.getOffset(), refCompressedData.size()); |
| } |
| |
| beginCommandBuffer(vk, *cmdBuffer); |
| vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); |
| |
| // Copy buffer to image |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &refSrcCopyBufferBarrierPre, 1u, &refSrcCopyImageBarrierPre); |
| vk.cmdCopyBufferToImage(*cmdBuffer, refSrcImageBuffer->get(), refSrcImage->get(), VK_IMAGE_LAYOUT_GENERAL, 1u, ©BufferToImageRegion); |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, DE_NULL, 1u, &refSrcCopyImageBarrierPost); |
| |
| // Make reference and result images readable |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &refDstInitImageBarrier); |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &resDstInitImageBarrier); |
| { |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &resCompressedImageBarrier); |
| } |
| |
| beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize); |
| { |
| DescriptorSetUpdateBuilder() |
| .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorRefSrcImage) |
| .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorResSrcImage) |
| .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorRefDstImage) |
| .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(3u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorResDstImage) |
| .update(vk, device); |
| |
| vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL); |
| vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &m_vertexBuffer->get(), &m_vertexBufferOffset); |
| vk.cmdDraw(*cmdBuffer, m_vertexCount, 1, 0, 0); |
| } |
| vk.cmdEndRenderPass(*cmdBuffer); |
| |
| // Decompress reference image |
| { |
| const VkImageMemoryBarrier refDstImageBarrier = makeImageMemoryBarrier( |
| VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, |
| VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, |
| refDstImage->get(), subresourceRange); |
| |
| const VkBufferMemoryBarrier refDstBufferBarrier = makeBufferMemoryBarrier( |
| VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, |
| refDstBuffer->get(), 0ull, dstBufferSize); |
| |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &refDstImageBarrier); |
| vk.cmdCopyImageToBuffer(*cmdBuffer, refDstImage->get(), VK_IMAGE_LAYOUT_GENERAL, refDstBuffer->get(), 1u, ©Region); |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &refDstBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); |
| } |
| |
| // Decompress result image |
| { |
| const VkImageMemoryBarrier resDstImageBarrier = makeImageMemoryBarrier( |
| VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, |
| VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, |
| resDstImage->get(), subresourceRange); |
| |
| const VkBufferMemoryBarrier resDstBufferBarrier = makeBufferMemoryBarrier( |
| VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, |
| resDstBuffer->get(), 0ull, dstBufferSize); |
| |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &resDstImageBarrier); |
| vk.cmdCopyImageToBuffer(*cmdBuffer, resDstImage->get(), VK_IMAGE_LAYOUT_GENERAL, resDstBuffer->get(), 1u, ©Region); |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &resDstBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); |
| } |
| |
| endCommandBuffer(vk, *cmdBuffer); |
| |
| submitCommandsAndWait(vk, device, queue, *cmdBuffer); |
| |
| // Compare decompressed pixel data in reference and result images |
| { |
| const Allocation& refDstBufferAlloc = refDstBuffer->getAllocation(); |
| invalidateMappedMemoryRange(vk, device, refDstBufferAlloc.getMemory(), refDstBufferAlloc.getOffset(), dstBufferSize); |
| |
| const Allocation& resDstBufferAlloc = resDstBuffer->getAllocation(); |
| invalidateMappedMemoryRange(vk, device, resDstBufferAlloc.getMemory(), resDstBufferAlloc.getOffset(), dstBufferSize); |
| |
| if (deMemCmp(refDstBufferAlloc.getHostPtr(), resDstBufferAlloc.getHostPtr(), (size_t)dstBufferSize) != 0) |
| { |
| // Do fuzzy to log error mask |
| invalidateMappedMemoryRange(vk, device, resDstBufferAlloc.getMemory(), resDstBufferAlloc.getOffset(), dstBufferSize); |
| invalidateMappedMemoryRange(vk, device, refDstBufferAlloc.getMemory(), refDstBufferAlloc.getOffset(), dstBufferSize); |
| |
| tcu::ConstPixelBufferAccess resPixels (mapVkFormat(m_parameters.formatForVerify), renderSize.width, renderSize.height, 1u, resDstBufferAlloc.getHostPtr()); |
| tcu::ConstPixelBufferAccess refPixels (mapVkFormat(m_parameters.formatForVerify), renderSize.width, renderSize.height, 1u, refDstBufferAlloc.getHostPtr()); |
| |
| string comment = string("Image Comparison (level=") + de::toString(level) + string(", layer=") + de::toString(layer) + string(")"); |
| |
| if (isWriteToCompressedOperation()) |
| tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ImageComparison", comment.c_str(), refPixels, resPixels, 0.001f, tcu::COMPARE_LOG_EVERYTHING); |
| else |
| tcu::fuzzyCompare(m_context.getTestContext().getLog(), "ImageComparison", comment.c_str(), resPixels, refPixels, 0.001f, tcu::COMPARE_LOG_EVERYTHING); |
| |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| |
| class GraphicsTextureTestInstance : public GraphicsAttachmentsTestInstance |
| { |
| public: |
| GraphicsTextureTestInstance (Context& context, const TestParameters& parameters); |
| |
| protected: |
| virtual bool isWriteToCompressedOperation (); |
| virtual void transcodeRead (); |
| virtual void transcodeWrite (); |
| }; |
| |
| GraphicsTextureTestInstance::GraphicsTextureTestInstance (Context& context, const TestParameters& parameters) |
| : GraphicsAttachmentsTestInstance(context, parameters) |
| { |
| } |
| |
| bool GraphicsTextureTestInstance::isWriteToCompressedOperation () |
| { |
| return (m_parameters.operation == OPERATION_TEXTURE_WRITE); |
| } |
| |
| void GraphicsTextureTestInstance::transcodeRead () |
| { |
| const DeviceInterface& vk = m_context.getDeviceInterface(); |
| const VkDevice device = m_context.getDevice(); |
| const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); |
| const VkQueue queue = m_context.getUniversalQueue(); |
| Allocator& allocator = m_context.getDefaultAllocator(); |
| |
| const VkImageCreateFlags* imgCreateFlagsOverride = DE_NULL; |
| |
| const VkImageCreateInfo srcImageCreateInfo = makeCreateImageInfo(m_srcFormat, m_parameters.imageType, m_srcImageResolutions[0], m_srcImageUsageFlags, imgCreateFlagsOverride, getLevelCount(), getLayerCount()); |
| MovePtr<Image> srcImage (new Image(vk, device, allocator, srcImageCreateInfo, MemoryRequirement::Any)); |
| |
| const Unique<VkShaderModule> vertShaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0)); |
| const Unique<VkShaderModule> fragShaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0)); |
| |
| const Unique<VkRenderPass> renderPass (makeRenderPass(vk, device)); |
| |
| const Move<VkDescriptorSetLayout> descriptorSetLayout (DescriptorSetLayoutBuilder() |
| .addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT) |
| .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT) |
| .build(vk, device)); |
| const Move<VkDescriptorPool> descriptorPool (DescriptorPoolBuilder() |
| .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) |
| .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) |
| .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); |
| const Move<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout)); |
| |
| const VkExtent2D renderSizeDummy (makeExtent2D(1u, 1u)); |
| const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout)); |
| const Unique<VkPipeline> pipeline (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertShaderModule, *fragShaderModule, renderSizeDummy, 0u, true)); |
| |
| 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)); |
| |
| for (deUint32 levelNdx = 0; levelNdx < getLevelCount(); ++levelNdx) |
| { |
| const UVec3& uncompressedImageRes = m_uncompressedImageResVec[levelNdx]; |
| const UVec3& srcImageResolution = m_srcImageResolutions[levelNdx]; |
| const UVec3& dstImageResolution = m_dstImageResolutions[levelNdx]; |
| const size_t srcImageSizeInBytes = m_srcData[levelNdx][0]->size(); |
| const size_t dstImageSizeInBytes = m_dstData[levelNdx][0]->size(); |
| const UVec3 srcImageResBlocked = getCompressedImageResolutionBlockCeil(m_parameters.formatCompressed, srcImageResolution); |
| |
| const VkImageCreateInfo dstImageCreateInfo = makeCreateImageInfo(m_dstFormat, m_parameters.imageType, dstImageResolution, m_dstImageUsageFlags, imgCreateFlagsOverride, SINGLE_LEVEL, SINGLE_LAYER); |
| |
| const VkBufferCreateInfo srcImageBufferInfo = makeBufferCreateInfo(srcImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); |
| const MovePtr<Buffer> srcImageBuffer = MovePtr<Buffer>(new Buffer(vk, device, allocator, srcImageBufferInfo, MemoryRequirement::HostVisible)); |
| |
| const VkBufferCreateInfo dstImageBufferInfo = makeBufferCreateInfo(dstImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT); |
| MovePtr<Buffer> dstImageBuffer = MovePtr<Buffer>(new Buffer(vk, device, allocator, dstImageBufferInfo, MemoryRequirement::HostVisible)); |
| |
| const VkExtent2D renderSize (makeExtent2D(uncompressedImageRes.x(), uncompressedImageRes.y())); |
| const VkViewport viewport = makeViewport(0.0f, 0.0f, static_cast<float>(renderSize.width), static_cast<float>(renderSize.height), 0.0f, 1.0f); |
| const VkRect2D scissor = makeScissor(renderSize.width, renderSize.height); |
| |
| for (deUint32 layerNdx = 0; layerNdx < getLayerCount(); ++layerNdx) |
| { |
| const VkImageSubresourceRange srcSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, levelNdx, SINGLE_LEVEL, layerNdx, SINGLE_LAYER); |
| const VkImageSubresourceRange dstSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, SINGLE_LEVEL, 0u, SINGLE_LAYER); |
| |
| Move<VkImageView> srcImageView (makeImageView(vk, device, srcImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed, srcSubresourceRange, m_srcImageViewUsageKHR)); |
| |
| de::MovePtr<Image> dstImage (new Image(vk, device, allocator, dstImageCreateInfo, MemoryRequirement::Any)); |
| Move<VkImageView> dstImageView (makeImageView(vk, device, dstImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed, dstSubresourceRange, m_dstImageViewUsageKHR)); |
| |
| const VkSamplerCreateInfo srcSamplerInfo (makeSamplerCreateInfo()); |
| const Move<VkSampler> srcSampler = vk::createSampler(vk, device, &srcSamplerInfo); |
| const VkDescriptorImageInfo descriptorSrcImage (makeDescriptorImageInfo(*srcSampler, *srcImageView, VK_IMAGE_LAYOUT_GENERAL)); |
| const VkDescriptorImageInfo descriptorDstImage (makeDescriptorImageInfo(DE_NULL, *dstImageView, VK_IMAGE_LAYOUT_GENERAL)); |
| |
| const VkBufferImageCopy srcCopyRegion = makeBufferImageCopy(srcImageResolution.x(), srcImageResolution.y(), levelNdx, layerNdx, srcImageResBlocked.x(), srcImageResBlocked.y()); |
| const VkBufferMemoryBarrier srcCopyBufferBarrierPre = makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, srcImageBuffer->get(), 0ull, srcImageSizeInBytes); |
| const VkImageMemoryBarrier srcCopyImageBarrierPre = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, srcImage->get(), srcSubresourceRange); |
| const VkImageMemoryBarrier srcCopyImageBarrierPost = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, srcImage->get(), srcSubresourceRange); |
| const VkBufferImageCopy dstCopyRegion = makeBufferImageCopy(dstImageResolution.x(), dstImageResolution.y()); |
| const VkImageMemoryBarrier dstInitImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, dstImage->get(), dstSubresourceRange); |
| |
| const VkExtent2D framebufferSize (makeExtent2D(dstImageResolution[0], dstImageResolution[1])); |
| const Move<VkFramebuffer> framebuffer (makeFramebuffer(vk, device, *renderPass, 0, DE_NULL, framebufferSize, SINGLE_LAYER)); |
| |
| // Upload source image data |
| const Allocation& alloc = srcImageBuffer->getAllocation(); |
| deMemcpy(alloc.getHostPtr(), &m_srcData[levelNdx][layerNdx]->at(0), srcImageSizeInBytes); |
| flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), srcImageSizeInBytes); |
| |
| beginCommandBuffer(vk, *cmdBuffer); |
| vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); |
| |
| // Copy buffer to image |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &srcCopyBufferBarrierPre, 1u, &srcCopyImageBarrierPre); |
| vk.cmdCopyBufferToImage(*cmdBuffer, srcImageBuffer->get(), srcImage->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &srcCopyRegion); |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &srcCopyImageBarrierPost); |
| |
| // Define destination image layout |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &dstInitImageBarrier); |
| |
| beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize); |
| |
| DescriptorSetUpdateBuilder() |
| .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorSrcImage) |
| .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorDstImage) |
| .update(vk, device); |
| |
| vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL); |
| vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &m_vertexBuffer->get(), &m_vertexBufferOffset); |
| |
| vk.cmdSetViewport(*cmdBuffer, 0u, 1u, &viewport); |
| vk.cmdSetScissor(*cmdBuffer, 0u, 1u, &scissor); |
| |
| vk.cmdDraw(*cmdBuffer, (deUint32)m_vertexCount, 1, 0, 0); |
| |
| vk.cmdEndRenderPass(*cmdBuffer); |
| |
| const VkImageMemoryBarrier prepareForTransferBarrier = makeImageMemoryBarrier( |
| VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, |
| VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, |
| dstImage->get(), dstSubresourceRange); |
| |
| const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier( |
| VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, |
| dstImageBuffer->get(), 0ull, dstImageSizeInBytes); |
| |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &prepareForTransferBarrier); |
| vk.cmdCopyImageToBuffer(*cmdBuffer, dstImage->get(), VK_IMAGE_LAYOUT_GENERAL, dstImageBuffer->get(), 1u, &dstCopyRegion); |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, ©Barrier, 0, (const VkImageMemoryBarrier*)DE_NULL); |
| |
| endCommandBuffer(vk, *cmdBuffer); |
| |
| submitCommandsAndWait(vk, device, queue, *cmdBuffer); |
| |
| const Allocation& dstImageBufferAlloc = dstImageBuffer->getAllocation(); |
| invalidateMappedMemoryRange(vk, device, dstImageBufferAlloc.getMemory(), dstImageBufferAlloc.getOffset(), dstImageSizeInBytes); |
| deMemcpy(&m_dstData[levelNdx][layerNdx]->at(0), dstImageBufferAlloc.getHostPtr(), dstImageSizeInBytes); |
| } |
| } |
| |
| m_compressedImage = srcImage; |
| } |
| |
| void GraphicsTextureTestInstance::transcodeWrite () |
| { |
| const DeviceInterface& vk = m_context.getDeviceInterface(); |
| const VkDevice device = m_context.getDevice(); |
| const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); |
| const VkQueue queue = m_context.getUniversalQueue(); |
| Allocator& allocator = m_context.getDefaultAllocator(); |
| |
| const VkImageCreateFlags* imgCreateFlagsOverride = DE_NULL; |
| |
| const VkImageCreateInfo dstImageCreateInfo = makeCreateImageInfo(m_dstFormat, m_parameters.imageType, m_dstImageResolutions[0], m_dstImageUsageFlags, imgCreateFlagsOverride, getLevelCount(), getLayerCount()); |
| MovePtr<Image> dstImage (new Image(vk, device, allocator, dstImageCreateInfo, MemoryRequirement::Any)); |
| |
| const Unique<VkShaderModule> vertShaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0)); |
| const Unique<VkShaderModule> fragShaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0)); |
| |
| const Unique<VkRenderPass> renderPass (makeRenderPass(vk, device)); |
| |
| const Move<VkDescriptorSetLayout> descriptorSetLayout (DescriptorSetLayoutBuilder() |
| .addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT) |
| .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT) |
| .build(vk, device)); |
| const Move<VkDescriptorPool> descriptorPool (DescriptorPoolBuilder() |
| .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) |
| .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) |
| .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); |
| const Move<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout)); |
| |
| const VkExtent2D renderSizeDummy (makeExtent2D(1u, 1u)); |
| const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout)); |
| const Unique<VkPipeline> pipeline (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertShaderModule, *fragShaderModule, renderSizeDummy, 0u, true)); |
| |
| 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)); |
| |
| for (deUint32 levelNdx = 0; levelNdx < getLevelCount(); ++levelNdx) |
| { |
| const UVec3& uncompressedImageRes = m_uncompressedImageResVec[levelNdx]; |
| const UVec3& srcImageResolution = m_srcImageResolutions[levelNdx]; |
| const UVec3& dstImageResolution = m_dstImageResolutions[levelNdx]; |
| const size_t srcImageSizeInBytes = m_srcData[levelNdx][0]->size(); |
| const size_t dstImageSizeInBytes = m_dstData[levelNdx][0]->size(); |
| const UVec3 dstImageResBlocked = getCompressedImageResolutionBlockCeil(m_parameters.formatCompressed, dstImageResolution); |
| |
| const VkImageCreateInfo srcImageCreateInfo = makeCreateImageInfo(m_srcFormat, m_parameters.imageType, srcImageResolution, m_srcImageUsageFlags, imgCreateFlagsOverride, SINGLE_LEVEL, SINGLE_LAYER); |
| |
| const VkExtent2D renderSize (makeExtent2D(uncompressedImageRes.x(), uncompressedImageRes.y())); |
| const VkViewport viewport = makeViewport(0.0f, 0.0f, static_cast<float>(renderSize.width), static_cast<float>(renderSize.height), 0.0f, 1.0f); |
| const VkRect2D scissor = makeScissor(renderSize.width, renderSize.height); |
| |
| for (deUint32 layerNdx = 0; layerNdx < getLayerCount(); ++layerNdx) |
| { |
| const VkBufferCreateInfo srcImageBufferInfo = makeBufferCreateInfo(srcImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); |
| const MovePtr<Buffer> srcImageBuffer = MovePtr<Buffer>(new Buffer(vk, device, allocator, srcImageBufferInfo, MemoryRequirement::HostVisible)); |
| |
| const VkBufferCreateInfo dstImageBufferInfo = makeBufferCreateInfo(dstImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT); |
| MovePtr<Buffer> dstImageBuffer = MovePtr<Buffer>(new Buffer(vk, device, allocator, dstImageBufferInfo, MemoryRequirement::HostVisible)); |
| |
| const VkImageSubresourceRange srcSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, SINGLE_LEVEL, 0u, SINGLE_LAYER); |
| const VkImageSubresourceRange dstSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, levelNdx, SINGLE_LEVEL, layerNdx, SINGLE_LAYER); |
| |
| Move<VkImageView> dstImageView (makeImageView(vk, device, dstImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed, dstSubresourceRange, m_dstImageViewUsageKHR)); |
| |
| de::MovePtr<Image> srcImage (new Image(vk, device, allocator, srcImageCreateInfo, MemoryRequirement::Any)); |
| Move<VkImageView> srcImageView (makeImageView(vk, device, srcImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.formatUncompressed, srcSubresourceRange, m_srcImageViewUsageKHR)); |
| |
| const VkSamplerCreateInfo srcSamplerInfo (makeSamplerCreateInfo()); |
| const Move<VkSampler> srcSampler = vk::createSampler(vk, device, &srcSamplerInfo); |
| const VkDescriptorImageInfo descriptorSrcImage (makeDescriptorImageInfo(*srcSampler, *srcImageView, VK_IMAGE_LAYOUT_GENERAL)); |
| const VkDescriptorImageInfo descriptorDstImage (makeDescriptorImageInfo(DE_NULL, *dstImageView, VK_IMAGE_LAYOUT_GENERAL)); |
| |
| const VkBufferImageCopy srcCopyRegion = makeBufferImageCopy(srcImageResolution.x(), srcImageResolution.y(), 0u, 0u); |
| const VkBufferMemoryBarrier srcCopyBufferBarrierPre = makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, srcImageBuffer->get(), 0ull, srcImageSizeInBytes); |
| const VkImageMemoryBarrier srcCopyImageBarrierPre = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, srcImage->get(), srcSubresourceRange); |
| const VkImageMemoryBarrier srcCopyImageBarrierPost = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, srcImage->get(), srcSubresourceRange); |
| const VkBufferImageCopy dstCopyRegion = makeBufferImageCopy(dstImageResolution.x(), dstImageResolution.y(), levelNdx, layerNdx, dstImageResBlocked.x(), dstImageResBlocked.y()); |
| const VkImageMemoryBarrier dstInitImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, dstImage->get(), dstSubresourceRange); |
| |
| const VkExtent2D framebufferSize (makeExtent2D(dstImageResolution[0], dstImageResolution[1])); |
| const Move<VkFramebuffer> framebuffer (makeFramebuffer(vk, device, *renderPass, 0, DE_NULL, framebufferSize, SINGLE_LAYER)); |
| |
| // Upload source image data |
| const Allocation& alloc = srcImageBuffer->getAllocation(); |
| deMemcpy(alloc.getHostPtr(), &m_srcData[levelNdx][layerNdx]->at(0), srcImageSizeInBytes); |
| flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), srcImageSizeInBytes); |
| |
| beginCommandBuffer(vk, *cmdBuffer); |
| vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); |
| |
| // Copy buffer to image |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &srcCopyBufferBarrierPre, 1u, &srcCopyImageBarrierPre); |
| vk.cmdCopyBufferToImage(*cmdBuffer, srcImageBuffer->get(), srcImage->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &srcCopyRegion); |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &srcCopyImageBarrierPost); |
| |
| // Define destination image layout |
| vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &dstInitImageBarrier); |
| |
| beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize); |
| |
| DescriptorSetUpdateBuilder() |
| .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorSrcImage) |
| .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u |