/*------------------------------------------------------------------------ * Vulkan Conformance Tests * ------------------------ * * Copyright (c) 2017 The Khronos Group Inc. * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Protected memory attachment render pass load tests *//*--------------------------------------------------------------------*/ #include "vktProtectedMemAttachmentLoadTests.hpp" #include "deRandom.hpp" #include "tcuTestLog.hpp" #include "tcuVector.hpp" #include "vkPrograms.hpp" #include "vktTestCase.hpp" #include "vktTestGroupUtil.hpp" #include "vkTypeUtil.hpp" #include "vkBuilderUtil.hpp" #include "vkCmdUtil.hpp" #include "vktProtectedMemContext.hpp" #include "vktProtectedMemUtils.hpp" #include "vktProtectedMemImageValidator.hpp" namespace vkt { namespace ProtectedMem { namespace { enum { RENDER_WIDTH = 128, RENDER_HEIGHT = 128, }; class AttachmentLoadTestInstance : public ProtectedTestInstance { public: AttachmentLoadTestInstance (Context& ctx, const vk::VkClearValue& clearValue, const ValidationData& refData, const ImageValidator& validator); virtual tcu::TestStatus iterate (void); private: const vk::VkFormat m_imageFormat; const vk::VkClearValue& m_clearValue; const ValidationData& m_refData; const ImageValidator& m_validator; }; class AttachmentLoadTestCase : public TestCase { public: AttachmentLoadTestCase (tcu::TestContext& testCtx, const std::string& name, vk::VkClearValue clearValue, ValidationData data) : TestCase (testCtx, name, "Clear on render pass initialization.") , m_clearValue (clearValue) , m_refData (data) { } virtual ~AttachmentLoadTestCase (void) {} virtual TestInstance* createInstance (Context& ctx) const { return new AttachmentLoadTestInstance(ctx, m_clearValue, m_refData, m_validator); } virtual void initPrograms (vk::SourceCollections& programCollection) const { m_validator.initPrograms(programCollection); } private: vk::VkClearValue m_clearValue; ValidationData m_refData; ImageValidator m_validator; }; AttachmentLoadTestInstance::AttachmentLoadTestInstance (Context& ctx, const vk::VkClearValue& clearValue, const ValidationData& refData, const ImageValidator& validator) : ProtectedTestInstance (ctx) , m_imageFormat (vk::VK_FORMAT_R8G8B8A8_UNORM) , m_clearValue (clearValue) , m_refData (refData) , m_validator (validator) { } tcu::TestStatus AttachmentLoadTestInstance::iterate() { ProtectedContext& ctx (m_protectedContext); const vk::DeviceInterface& vk = ctx.getDeviceInterface(); const vk::VkDevice device = ctx.getDevice(); const vk::VkQueue queue = ctx.getQueue(); const deUint32 queueFamilyIndex = ctx.getQueueFamilyIndex(); // Create output image de::MovePtr colorImage (createImage2D(ctx, PROTECTION_ENABLED, queueFamilyIndex, RENDER_WIDTH, RENDER_HEIGHT, m_imageFormat, vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|vk::VK_IMAGE_USAGE_SAMPLED_BIT)); vk::Unique colorImageView (createImageView(ctx, **colorImage, m_imageFormat)); vk::Unique renderPass (createRenderPass(ctx, m_imageFormat)); vk::Unique framebuffer (createFramebuffer(ctx, RENDER_WIDTH, RENDER_HEIGHT, *renderPass, *colorImageView)); vk::Unique pipelineLayout (createPipelineLayout(ctx, 0u, DE_NULL)); vk::Unique cmdPool (makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex)); vk::Unique cmdBuffer (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY)); // Begin cmd buffer beginCommandBuffer(vk, *cmdBuffer); // Start image barrier { const vk::VkImageMemoryBarrier startImgBarrier = { vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType DE_NULL, // pNext 0, // srcAccessMask vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // dstAccessMask vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout queueFamilyIndex, // srcQueueFamilyIndex queueFamilyIndex, // dstQueueFamilyIndex **colorImage, // image { vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask 0u, // baseMipLevel 1u, // mipLevels 0u, // baseArraySlice 1u, // subresourceRange } }; vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &startImgBarrier); } // Image clear beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, vk::makeRect2D(0, 0, RENDER_WIDTH, RENDER_HEIGHT), m_clearValue); endRenderPass(vk, *cmdBuffer); { // Image validator reads image in compute shader const vk::VkImageMemoryBarrier endImgBarrier = { vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType DE_NULL, // pNext vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask vk::VK_ACCESS_SHADER_READ_BIT, // dstAccessMask vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // newLayout queueFamilyIndex, // srcQueueFamilyIndex queueFamilyIndex, // dstQueueFamilyIndex **colorImage, // image { vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask 0u, // baseMipLevel 1u, // mipLevels 0u, // baseArraySlice 1u, // subresourceRange } }; vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &endImgBarrier); } endCommandBuffer(vk, *cmdBuffer); // Submit command buffer const vk::Unique fence (vk::createFence(vk, device)); VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull)); // Log out test data ctx.getTestContext().getLog() << tcu::TestLog::Message << "Color clear value: " << tcu::Vec4(m_clearValue.color.float32) << tcu::TestLog::EndMessage << tcu::TestLog::Message << "Depth clear value: " << m_clearValue.depthStencil.depth << tcu::TestLog::EndMessage << tcu::TestLog::Message << "Stencil clear value: " << m_clearValue.depthStencil.stencil << tcu::TestLog::EndMessage; // Validate resulting image if (m_validator.validateImage(ctx, m_refData, **colorImage, m_imageFormat, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)) return tcu::TestStatus::pass("Everything went OK"); else return tcu::TestStatus::fail("Something went really wrong"); } } // anonymous tcu::TestCaseGroup* createAttachmentLoadTests (tcu::TestContext& testCtx) { struct { const vk::VkClearValue clearValue; const ValidationData data; } testData[] = { { vk::makeClearValueColorF32(1.0f, 0.0f, 0.0f, 1.0f), { { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f), tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), }, { tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), } } }, { vk::makeClearValueColorF32(0.0f, 1.0f, 0.0f, 1.0f), { { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f), tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), }, { tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), } } }, { vk::makeClearValueColorF32(0.0f, 0.0f, 1.0f, 1.0f), { { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f), tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), }, { tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), } } }, { vk::makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f), { { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f), tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), }, { tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), } } }, { vk::makeClearValueColorF32(1.0f, 0.0f, 0.0f, 1.0f), { { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f), tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), }, { tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), } } }, { vk::makeClearValueColorF32(1.0f, 0.0f, 0.0f, 0.0f), { { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f), tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), }, { tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), } } }, { vk::makeClearValueColorF32(0.1f, 0.2f, 0.3f, 0.0f), { { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f), tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), }, { tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), } } }, }; de::MovePtr loadStaticTests (new tcu::TestCaseGroup(testCtx, "static", "Attachment Load Op Tests with static input")); for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx) { const std::string name = "clear_" + de::toString(ndx + 1); loadStaticTests->addChild(new AttachmentLoadTestCase(testCtx, name.c_str(), testData[ndx].clearValue, testData[ndx].data)); } /* Add a few randomized tests */ de::MovePtr loadRandomTests (new tcu::TestCaseGroup(testCtx, "random", "Attachment Load Op Tests with random input")); const int testCount = 10; de::Random rnd (testCtx.getCommandLine().getBaseSeed()); for (int ndx = 0; ndx < testCount; ++ndx) { const std::string name = "clear_" + de::toString(ndx + 1); vk::VkClearValue clearValue = vk::makeClearValueColorF32( rnd.getFloat(0.0, 1.0f), rnd.getFloat(0.0, 1.0f), rnd.getFloat(0.0, 1.0f), rnd.getFloat(0.0, 1.0f)); tcu::Vec4 refValue (clearValue.color.float32[0], clearValue.color.float32[1], clearValue.color.float32[2], clearValue.color.float32[3]); ValidationData data = { { tcu::Vec4(rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f)), tcu::Vec4(rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f)), tcu::Vec4(rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f)), tcu::Vec4(rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f)) }, { refValue, refValue, refValue, refValue } }; loadRandomTests->addChild(new AttachmentLoadTestCase(testCtx, name.c_str(), clearValue, data)); } de::MovePtr loadTests (new tcu::TestCaseGroup(testCtx, "load_op", "Attachment Load Op Tests")); loadTests->addChild(loadStaticTests.release()); loadTests->addChild(loadRandomTests.release()); return loadTests.release(); } } // ProtectedMem } // vkt