1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------ 2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests 3e5c31af7Sopenharmony_ci * ------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2015 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * Copyright (c) 2015 Intel Corporation 7e5c31af7Sopenharmony_ci * Copyright (c) 2023 LunarG, Inc. 8e5c31af7Sopenharmony_ci * Copyright (c) 2023 Nintendo 9e5c31af7Sopenharmony_ci * 10e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 11e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 12e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 13e5c31af7Sopenharmony_ci * 14e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 15e5c31af7Sopenharmony_ci * 16e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 17e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 18e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 20e5c31af7Sopenharmony_ci * limitations under the License. 21e5c31af7Sopenharmony_ci * 22e5c31af7Sopenharmony_ci *//*! 23e5c31af7Sopenharmony_ci * \file 24e5c31af7Sopenharmony_ci * \brief Dynamic State Tests - General 25e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 26e5c31af7Sopenharmony_ci 27e5c31af7Sopenharmony_ci#include "vktDynamicStateGeneralTests.hpp" 28e5c31af7Sopenharmony_ci 29e5c31af7Sopenharmony_ci#include "vktTestCaseUtil.hpp" 30e5c31af7Sopenharmony_ci#include "vktDynamicStateTestCaseUtil.hpp" 31e5c31af7Sopenharmony_ci#include "vktDynamicStateBaseClass.hpp" 32e5c31af7Sopenharmony_ci#include "vktDrawCreateInfoUtil.hpp" 33e5c31af7Sopenharmony_ci#include "vktDrawImageObjectUtil.hpp" 34e5c31af7Sopenharmony_ci#include "vktDrawBufferObjectUtil.hpp" 35e5c31af7Sopenharmony_ci 36e5c31af7Sopenharmony_ci#include "vkImageUtil.hpp" 37e5c31af7Sopenharmony_ci#include "vkCmdUtil.hpp" 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 40e5c31af7Sopenharmony_ci#include "tcuResource.hpp" 41e5c31af7Sopenharmony_ci#include "tcuImageCompare.hpp" 42e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp" 43e5c31af7Sopenharmony_ci#include "tcuRGBA.hpp" 44e5c31af7Sopenharmony_ci 45e5c31af7Sopenharmony_ci#include "vkDefs.hpp" 46e5c31af7Sopenharmony_ci#include "vkCmdUtil.hpp" 47e5c31af7Sopenharmony_ci 48e5c31af7Sopenharmony_cinamespace vkt 49e5c31af7Sopenharmony_ci{ 50e5c31af7Sopenharmony_cinamespace DynamicState 51e5c31af7Sopenharmony_ci{ 52e5c31af7Sopenharmony_ci 53e5c31af7Sopenharmony_ciusing namespace Draw; 54e5c31af7Sopenharmony_ci 55e5c31af7Sopenharmony_cinamespace 56e5c31af7Sopenharmony_ci{ 57e5c31af7Sopenharmony_ci 58e5c31af7Sopenharmony_ciclass StateSwitchTestInstance : public DynamicStateBaseClass 59e5c31af7Sopenharmony_ci{ 60e5c31af7Sopenharmony_cipublic: 61e5c31af7Sopenharmony_ci StateSwitchTestInstance (Context &context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders) 62e5c31af7Sopenharmony_ci : DynamicStateBaseClass (context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH)) 63e5c31af7Sopenharmony_ci { 64e5c31af7Sopenharmony_ci m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec())); 65e5c31af7Sopenharmony_ci m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec())); 66e5c31af7Sopenharmony_ci m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec())); 67e5c31af7Sopenharmony_ci m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec())); 68e5c31af7Sopenharmony_ci 69e5c31af7Sopenharmony_ci DynamicStateBaseClass::initialize(); 70e5c31af7Sopenharmony_ci } 71e5c31af7Sopenharmony_ci 72e5c31af7Sopenharmony_ci virtual tcu::TestStatus iterate (void) 73e5c31af7Sopenharmony_ci { 74e5c31af7Sopenharmony_ci tcu::TestLog& log = m_context.getTestContext().getLog(); 75e5c31af7Sopenharmony_ci const vk::VkQueue queue = m_context.getUniversalQueue(); 76e5c31af7Sopenharmony_ci const vk::VkDevice device = m_context.getDevice(); 77e5c31af7Sopenharmony_ci 78e5c31af7Sopenharmony_ci beginRenderPass(); 79e5c31af7Sopenharmony_ci 80e5c31af7Sopenharmony_ci // bind states here 81e5c31af7Sopenharmony_ci vk::VkViewport viewport = { 0, 0, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f }; 82e5c31af7Sopenharmony_ci vk::VkRect2D scissor_1 = { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } }; 83e5c31af7Sopenharmony_ci vk::VkRect2D scissor_2 = { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } }; 84e5c31af7Sopenharmony_ci 85e5c31af7Sopenharmony_ci setDynamicRasterizationState(); 86e5c31af7Sopenharmony_ci setDynamicBlendState(); 87e5c31af7Sopenharmony_ci setDynamicDepthStencilState(); 88e5c31af7Sopenharmony_ci 89e5c31af7Sopenharmony_ci m_pipeline.bind(*m_cmdBuffer); 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 92e5c31af7Sopenharmony_ci if (m_isMesh) 93e5c31af7Sopenharmony_ci { 94e5c31af7Sopenharmony_ci const auto numVert = static_cast<uint32_t>(m_data.size()); 95e5c31af7Sopenharmony_ci DE_ASSERT(numVert >= 2u); 96e5c31af7Sopenharmony_ci 97e5c31af7Sopenharmony_ci m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr); 98e5c31af7Sopenharmony_ci pushVertexOffset(0u, *m_pipelineLayout); 99e5c31af7Sopenharmony_ci 100e5c31af7Sopenharmony_ci // bind first state 101e5c31af7Sopenharmony_ci setDynamicViewportState(1, &viewport, &scissor_1); 102e5c31af7Sopenharmony_ci m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, numVert - 2u, 1u, 1u); 103e5c31af7Sopenharmony_ci 104e5c31af7Sopenharmony_ci // bind second state 105e5c31af7Sopenharmony_ci setDynamicViewportState(1, &viewport, &scissor_2); 106e5c31af7Sopenharmony_ci m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, numVert - 2u, 1u, 1u); 107e5c31af7Sopenharmony_ci } 108e5c31af7Sopenharmony_ci else 109e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 110e5c31af7Sopenharmony_ci { 111e5c31af7Sopenharmony_ci const vk::VkDeviceSize vertexBufferOffset = 0; 112e5c31af7Sopenharmony_ci const vk::VkBuffer vertexBuffer = m_vertexBuffer->object(); 113e5c31af7Sopenharmony_ci m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset); 114e5c31af7Sopenharmony_ci 115e5c31af7Sopenharmony_ci // bind first state 116e5c31af7Sopenharmony_ci setDynamicViewportState(1, &viewport, &scissor_1); 117e5c31af7Sopenharmony_ci m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0); 118e5c31af7Sopenharmony_ci 119e5c31af7Sopenharmony_ci // bind second state 120e5c31af7Sopenharmony_ci setDynamicViewportState(1, &viewport, &scissor_2); 121e5c31af7Sopenharmony_ci m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0); 122e5c31af7Sopenharmony_ci } 123e5c31af7Sopenharmony_ci 124e5c31af7Sopenharmony_ci m_renderPass.end(m_vk, *m_cmdBuffer); 125e5c31af7Sopenharmony_ci endCommandBuffer(m_vk, *m_cmdBuffer); 126e5c31af7Sopenharmony_ci 127e5c31af7Sopenharmony_ci submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get()); 128e5c31af7Sopenharmony_ci 129e5c31af7Sopenharmony_ci //validation 130e5c31af7Sopenharmony_ci tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT))); 131e5c31af7Sopenharmony_ci referenceFrame.allocLevel(0); 132e5c31af7Sopenharmony_ci 133e5c31af7Sopenharmony_ci const deInt32 frameWidth = referenceFrame.getWidth(); 134e5c31af7Sopenharmony_ci const deInt32 frameHeight = referenceFrame.getHeight(); 135e5c31af7Sopenharmony_ci 136e5c31af7Sopenharmony_ci tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 137e5c31af7Sopenharmony_ci 138e5c31af7Sopenharmony_ci for (int y = 0; y < frameHeight; y++) 139e5c31af7Sopenharmony_ci { 140e5c31af7Sopenharmony_ci const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f; 141e5c31af7Sopenharmony_ci 142e5c31af7Sopenharmony_ci for (int x = 0; x < frameWidth; x++) 143e5c31af7Sopenharmony_ci { 144e5c31af7Sopenharmony_ci const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f; 145e5c31af7Sopenharmony_ci 146e5c31af7Sopenharmony_ci if ((yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f) || 147e5c31af7Sopenharmony_ci (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f)) 148e5c31af7Sopenharmony_ci referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y); 149e5c31af7Sopenharmony_ci } 150e5c31af7Sopenharmony_ci } 151e5c31af7Sopenharmony_ci 152e5c31af7Sopenharmony_ci const vk::VkOffset3D zeroOffset = { 0, 0, 0 }; 153e5c31af7Sopenharmony_ci const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), 154e5c31af7Sopenharmony_ci vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, 155e5c31af7Sopenharmony_ci vk::VK_IMAGE_ASPECT_COLOR_BIT); 156e5c31af7Sopenharmony_ci 157e5c31af7Sopenharmony_ci if (!tcu::fuzzyCompare(log, "Result", "Image comparison result", 158e5c31af7Sopenharmony_ci referenceFrame.getLevel(0), renderedFrame, 0.05f, 159e5c31af7Sopenharmony_ci tcu::COMPARE_LOG_RESULT)) 160e5c31af7Sopenharmony_ci { 161e5c31af7Sopenharmony_ci 162e5c31af7Sopenharmony_ci return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed"); 163e5c31af7Sopenharmony_ci } 164e5c31af7Sopenharmony_ci 165e5c31af7Sopenharmony_ci return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed"); 166e5c31af7Sopenharmony_ci } 167e5c31af7Sopenharmony_ci}; 168e5c31af7Sopenharmony_ci 169e5c31af7Sopenharmony_ciclass BindOrderTestInstance : public DynamicStateBaseClass 170e5c31af7Sopenharmony_ci{ 171e5c31af7Sopenharmony_cipublic: 172e5c31af7Sopenharmony_ci BindOrderTestInstance (Context& context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders) 173e5c31af7Sopenharmony_ci : DynamicStateBaseClass (context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH)) 174e5c31af7Sopenharmony_ci { 175e5c31af7Sopenharmony_ci m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec())); 176e5c31af7Sopenharmony_ci m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec())); 177e5c31af7Sopenharmony_ci m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec())); 178e5c31af7Sopenharmony_ci m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec())); 179e5c31af7Sopenharmony_ci 180e5c31af7Sopenharmony_ci DynamicStateBaseClass::initialize(); 181e5c31af7Sopenharmony_ci } 182e5c31af7Sopenharmony_ci 183e5c31af7Sopenharmony_ci virtual tcu::TestStatus iterate (void) 184e5c31af7Sopenharmony_ci { 185e5c31af7Sopenharmony_ci tcu::TestLog &log = m_context.getTestContext().getLog(); 186e5c31af7Sopenharmony_ci const vk::VkQueue queue = m_context.getUniversalQueue(); 187e5c31af7Sopenharmony_ci const vk::VkDevice device = m_context.getDevice(); 188e5c31af7Sopenharmony_ci 189e5c31af7Sopenharmony_ci beginRenderPass(); 190e5c31af7Sopenharmony_ci 191e5c31af7Sopenharmony_ci // bind states here 192e5c31af7Sopenharmony_ci vk::VkViewport viewport = { 0.0f, 0.0f, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f }; 193e5c31af7Sopenharmony_ci vk::VkRect2D scissor_1 = { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } }; 194e5c31af7Sopenharmony_ci vk::VkRect2D scissor_2 = { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } }; 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_ci setDynamicRasterizationState(); 197e5c31af7Sopenharmony_ci setDynamicBlendState(); 198e5c31af7Sopenharmony_ci setDynamicDepthStencilState(); 199e5c31af7Sopenharmony_ci setDynamicViewportState(1, &viewport, &scissor_1); 200e5c31af7Sopenharmony_ci 201e5c31af7Sopenharmony_ci m_pipeline.bind(*m_cmdBuffer); 202e5c31af7Sopenharmony_ci 203e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 204e5c31af7Sopenharmony_ci if (m_isMesh) 205e5c31af7Sopenharmony_ci { 206e5c31af7Sopenharmony_ci const auto numVert = static_cast<uint32_t>(m_data.size()); 207e5c31af7Sopenharmony_ci DE_ASSERT(numVert >= 2u); 208e5c31af7Sopenharmony_ci 209e5c31af7Sopenharmony_ci m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr); 210e5c31af7Sopenharmony_ci pushVertexOffset(0u, *m_pipelineLayout); 211e5c31af7Sopenharmony_ci 212e5c31af7Sopenharmony_ci // rebind in different order 213e5c31af7Sopenharmony_ci setDynamicBlendState(); 214e5c31af7Sopenharmony_ci setDynamicRasterizationState(); 215e5c31af7Sopenharmony_ci setDynamicDepthStencilState(); 216e5c31af7Sopenharmony_ci 217e5c31af7Sopenharmony_ci // bind first state 218e5c31af7Sopenharmony_ci setDynamicViewportState(1, &viewport, &scissor_1); 219e5c31af7Sopenharmony_ci m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, numVert - 2u, 1u, 1u); 220e5c31af7Sopenharmony_ci 221e5c31af7Sopenharmony_ci setDynamicViewportState(1, &viewport, &scissor_2); 222e5c31af7Sopenharmony_ci m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, numVert - 2u, 1u, 1u); 223e5c31af7Sopenharmony_ci } 224e5c31af7Sopenharmony_ci else 225e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 226e5c31af7Sopenharmony_ci { 227e5c31af7Sopenharmony_ci const vk::VkDeviceSize vertexBufferOffset = 0; 228e5c31af7Sopenharmony_ci const vk::VkBuffer vertexBuffer = m_vertexBuffer->object(); 229e5c31af7Sopenharmony_ci m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset); 230e5c31af7Sopenharmony_ci 231e5c31af7Sopenharmony_ci // rebind in different order 232e5c31af7Sopenharmony_ci setDynamicBlendState(); 233e5c31af7Sopenharmony_ci setDynamicRasterizationState(); 234e5c31af7Sopenharmony_ci setDynamicDepthStencilState(); 235e5c31af7Sopenharmony_ci 236e5c31af7Sopenharmony_ci // bind first state 237e5c31af7Sopenharmony_ci setDynamicViewportState(1, &viewport, &scissor_1); 238e5c31af7Sopenharmony_ci m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0); 239e5c31af7Sopenharmony_ci 240e5c31af7Sopenharmony_ci setDynamicViewportState(1, &viewport, &scissor_2); 241e5c31af7Sopenharmony_ci m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0); 242e5c31af7Sopenharmony_ci } 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_ci m_renderPass.end(m_vk, *m_cmdBuffer); 245e5c31af7Sopenharmony_ci endCommandBuffer(m_vk, *m_cmdBuffer); 246e5c31af7Sopenharmony_ci 247e5c31af7Sopenharmony_ci submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get()); 248e5c31af7Sopenharmony_ci 249e5c31af7Sopenharmony_ci //validation 250e5c31af7Sopenharmony_ci tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT))); 251e5c31af7Sopenharmony_ci referenceFrame.allocLevel(0); 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_ci const deInt32 frameWidth = referenceFrame.getWidth(); 254e5c31af7Sopenharmony_ci const deInt32 frameHeight = referenceFrame.getHeight(); 255e5c31af7Sopenharmony_ci 256e5c31af7Sopenharmony_ci tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 257e5c31af7Sopenharmony_ci 258e5c31af7Sopenharmony_ci for (int y = 0; y < frameHeight; y++) 259e5c31af7Sopenharmony_ci { 260e5c31af7Sopenharmony_ci const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f; 261e5c31af7Sopenharmony_ci 262e5c31af7Sopenharmony_ci for (int x = 0; x < frameWidth; x++) 263e5c31af7Sopenharmony_ci { 264e5c31af7Sopenharmony_ci const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f; 265e5c31af7Sopenharmony_ci 266e5c31af7Sopenharmony_ci if ((yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f) || 267e5c31af7Sopenharmony_ci (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f)) 268e5c31af7Sopenharmony_ci referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y); 269e5c31af7Sopenharmony_ci } 270e5c31af7Sopenharmony_ci } 271e5c31af7Sopenharmony_ci 272e5c31af7Sopenharmony_ci const vk::VkOffset3D zeroOffset = { 0, 0, 0 }; 273e5c31af7Sopenharmony_ci const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), 274e5c31af7Sopenharmony_ci vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT); 275e5c31af7Sopenharmony_ci 276e5c31af7Sopenharmony_ci if (!tcu::fuzzyCompare(log, "Result", "Image comparison result", 277e5c31af7Sopenharmony_ci referenceFrame.getLevel(0), renderedFrame, 0.05f, 278e5c31af7Sopenharmony_ci tcu::COMPARE_LOG_RESULT)) 279e5c31af7Sopenharmony_ci { 280e5c31af7Sopenharmony_ci return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed"); 281e5c31af7Sopenharmony_ci } 282e5c31af7Sopenharmony_ci 283e5c31af7Sopenharmony_ci return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed"); 284e5c31af7Sopenharmony_ci } 285e5c31af7Sopenharmony_ci}; 286e5c31af7Sopenharmony_ci 287e5c31af7Sopenharmony_ciclass StatePersistenceTestInstance : public DynamicStateBaseClass 288e5c31af7Sopenharmony_ci{ 289e5c31af7Sopenharmony_ciprotected: 290e5c31af7Sopenharmony_ci vk::GraphicsPipelineWrapper m_pipelineAdditional; 291e5c31af7Sopenharmony_ci 292e5c31af7Sopenharmony_cipublic: 293e5c31af7Sopenharmony_ci StatePersistenceTestInstance (Context& context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders) 294e5c31af7Sopenharmony_ci : DynamicStateBaseClass (context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH)) 295e5c31af7Sopenharmony_ci , m_pipelineAdditional (context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), context.getDeviceExtensions(), pipelineConstructionType) 296e5c31af7Sopenharmony_ci { 297e5c31af7Sopenharmony_ci // This test does not make sense for mesh shader variants. 298e5c31af7Sopenharmony_ci DE_ASSERT(!m_isMesh); 299e5c31af7Sopenharmony_ci 300e5c31af7Sopenharmony_ci m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec())); 301e5c31af7Sopenharmony_ci m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec())); 302e5c31af7Sopenharmony_ci m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec())); 303e5c31af7Sopenharmony_ci m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec())); 304e5c31af7Sopenharmony_ci 305e5c31af7Sopenharmony_ci m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec())); 306e5c31af7Sopenharmony_ci m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec())); 307e5c31af7Sopenharmony_ci m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec())); 308e5c31af7Sopenharmony_ci m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec())); 309e5c31af7Sopenharmony_ci m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec())); 310e5c31af7Sopenharmony_ci m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec())); 311e5c31af7Sopenharmony_ci 312e5c31af7Sopenharmony_ci DynamicStateBaseClass::initialize(); 313e5c31af7Sopenharmony_ci } 314e5c31af7Sopenharmony_ci virtual void initPipeline (const vk::VkDevice device) 315e5c31af7Sopenharmony_ci { 316e5c31af7Sopenharmony_ci const vk::ShaderWrapper vs (vk::ShaderWrapper(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0)); 317e5c31af7Sopenharmony_ci const vk::ShaderWrapper fs (vk::ShaderWrapper(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0)); 318e5c31af7Sopenharmony_ci std::vector<vk::VkViewport> viewports { { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }; 319e5c31af7Sopenharmony_ci std::vector<vk::VkRect2D> scissors { { { 0u, 0u }, { 0u, 0u } } }; 320e5c31af7Sopenharmony_ci 321e5c31af7Sopenharmony_ci const PipelineCreateInfo::ColorBlendState::Attachment attachmentState; 322e5c31af7Sopenharmony_ci const PipelineCreateInfo::ColorBlendState colorBlendState(1, static_cast<const vk::VkPipelineColorBlendAttachmentState*>(&attachmentState)); 323e5c31af7Sopenharmony_ci const PipelineCreateInfo::RasterizerState rasterizerState; 324e5c31af7Sopenharmony_ci const PipelineCreateInfo::DepthStencilState depthStencilState; 325e5c31af7Sopenharmony_ci const PipelineCreateInfo::DynamicState dynamicState; 326e5c31af7Sopenharmony_ci 327e5c31af7Sopenharmony_ci m_pipeline.setDefaultTopology(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP) 328e5c31af7Sopenharmony_ci .setDynamicState(static_cast<const vk::VkPipelineDynamicStateCreateInfo*>(&dynamicState)) 329e5c31af7Sopenharmony_ci .setDefaultMultisampleState() 330e5c31af7Sopenharmony_ci .setupVertexInputState(&m_vertexInputState) 331e5c31af7Sopenharmony_ci .setupPreRasterizationShaderState(viewports, 332e5c31af7Sopenharmony_ci scissors, 333e5c31af7Sopenharmony_ci m_pipelineLayout, 334e5c31af7Sopenharmony_ci *m_renderPass, 335e5c31af7Sopenharmony_ci 0u, 336e5c31af7Sopenharmony_ci vs, 337e5c31af7Sopenharmony_ci static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState)) 338e5c31af7Sopenharmony_ci .setupFragmentShaderState(m_pipelineLayout, *m_renderPass, 0u, fs, static_cast<const vk::VkPipelineDepthStencilStateCreateInfo*>(&depthStencilState)) 339e5c31af7Sopenharmony_ci .setupFragmentOutputState(*m_renderPass, 0u, static_cast<const vk::VkPipelineColorBlendStateCreateInfo*>(&colorBlendState)) 340e5c31af7Sopenharmony_ci .setMonolithicPipelineLayout(m_pipelineLayout) 341e5c31af7Sopenharmony_ci .buildPipeline(); 342e5c31af7Sopenharmony_ci 343e5c31af7Sopenharmony_ci m_pipelineAdditional.setDefaultTopology(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) 344e5c31af7Sopenharmony_ci .setDynamicState(static_cast<const vk::VkPipelineDynamicStateCreateInfo*>(&dynamicState)) 345e5c31af7Sopenharmony_ci .setDefaultMultisampleState() 346e5c31af7Sopenharmony_ci .setupVertexInputState(&m_vertexInputState) 347e5c31af7Sopenharmony_ci .setupPreRasterizationShaderState(viewports, 348e5c31af7Sopenharmony_ci scissors, 349e5c31af7Sopenharmony_ci m_pipelineLayout, 350e5c31af7Sopenharmony_ci *m_renderPass, 351e5c31af7Sopenharmony_ci 0u, 352e5c31af7Sopenharmony_ci vs, 353e5c31af7Sopenharmony_ci static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState)) 354e5c31af7Sopenharmony_ci .setupFragmentShaderState(m_pipelineLayout, *m_renderPass, 0u, fs, static_cast<const vk::VkPipelineDepthStencilStateCreateInfo*>(&depthStencilState)) 355e5c31af7Sopenharmony_ci .setupFragmentOutputState(*m_renderPass, 0u, static_cast<const vk::VkPipelineColorBlendStateCreateInfo*>(&colorBlendState)) 356e5c31af7Sopenharmony_ci .setMonolithicPipelineLayout(m_pipelineLayout) 357e5c31af7Sopenharmony_ci .buildPipeline(); 358e5c31af7Sopenharmony_ci } 359e5c31af7Sopenharmony_ci 360e5c31af7Sopenharmony_ci virtual tcu::TestStatus iterate(void) 361e5c31af7Sopenharmony_ci { 362e5c31af7Sopenharmony_ci tcu::TestLog& log = m_context.getTestContext().getLog(); 363e5c31af7Sopenharmony_ci const vk::VkQueue queue = m_context.getUniversalQueue(); 364e5c31af7Sopenharmony_ci const vk::VkDevice device = m_context.getDevice(); 365e5c31af7Sopenharmony_ci 366e5c31af7Sopenharmony_ci beginRenderPass(); 367e5c31af7Sopenharmony_ci 368e5c31af7Sopenharmony_ci // bind states here 369e5c31af7Sopenharmony_ci const vk::VkViewport viewport = { 0.0f, 0.0f, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f }; 370e5c31af7Sopenharmony_ci const vk::VkRect2D scissor_1 = { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } }; 371e5c31af7Sopenharmony_ci const vk::VkRect2D scissor_2 = { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } }; 372e5c31af7Sopenharmony_ci 373e5c31af7Sopenharmony_ci setDynamicRasterizationState(); 374e5c31af7Sopenharmony_ci setDynamicBlendState(); 375e5c31af7Sopenharmony_ci setDynamicDepthStencilState(); 376e5c31af7Sopenharmony_ci 377e5c31af7Sopenharmony_ci m_pipeline.bind(*m_cmdBuffer); 378e5c31af7Sopenharmony_ci 379e5c31af7Sopenharmony_ci const vk::VkDeviceSize vertexBufferOffset = 0; 380e5c31af7Sopenharmony_ci const vk::VkBuffer vertexBuffer = m_vertexBuffer->object(); 381e5c31af7Sopenharmony_ci m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset); 382e5c31af7Sopenharmony_ci 383e5c31af7Sopenharmony_ci // bind first state 384e5c31af7Sopenharmony_ci setDynamicViewportState(1, &viewport, &scissor_1); 385e5c31af7Sopenharmony_ci // draw quad using vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP 386e5c31af7Sopenharmony_ci m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0); 387e5c31af7Sopenharmony_ci 388e5c31af7Sopenharmony_ci m_pipelineAdditional.bind(*m_cmdBuffer); 389e5c31af7Sopenharmony_ci 390e5c31af7Sopenharmony_ci // bind second state 391e5c31af7Sopenharmony_ci setDynamicViewportState(1, &viewport, &scissor_2); 392e5c31af7Sopenharmony_ci // draw quad using vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST 393e5c31af7Sopenharmony_ci m_vk.cmdDraw(*m_cmdBuffer, 6, 1, 4, 0); 394e5c31af7Sopenharmony_ci 395e5c31af7Sopenharmony_ci m_renderPass.end(m_vk, *m_cmdBuffer); 396e5c31af7Sopenharmony_ci endCommandBuffer(m_vk, *m_cmdBuffer); 397e5c31af7Sopenharmony_ci 398e5c31af7Sopenharmony_ci submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get()); 399e5c31af7Sopenharmony_ci 400e5c31af7Sopenharmony_ci //validation 401e5c31af7Sopenharmony_ci tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT))); 402e5c31af7Sopenharmony_ci referenceFrame.allocLevel(0); 403e5c31af7Sopenharmony_ci 404e5c31af7Sopenharmony_ci const deInt32 frameWidth = referenceFrame.getWidth(); 405e5c31af7Sopenharmony_ci const deInt32 frameHeight = referenceFrame.getHeight(); 406e5c31af7Sopenharmony_ci 407e5c31af7Sopenharmony_ci tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 408e5c31af7Sopenharmony_ci 409e5c31af7Sopenharmony_ci for (int y = 0; y < frameHeight; y++) 410e5c31af7Sopenharmony_ci { 411e5c31af7Sopenharmony_ci const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f; 412e5c31af7Sopenharmony_ci 413e5c31af7Sopenharmony_ci for (int x = 0; x < frameWidth; x++) 414e5c31af7Sopenharmony_ci { 415e5c31af7Sopenharmony_ci const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f; 416e5c31af7Sopenharmony_ci 417e5c31af7Sopenharmony_ci if (yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f) 418e5c31af7Sopenharmony_ci referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y); 419e5c31af7Sopenharmony_ci else if (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f) 420e5c31af7Sopenharmony_ci referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y); 421e5c31af7Sopenharmony_ci } 422e5c31af7Sopenharmony_ci } 423e5c31af7Sopenharmony_ci 424e5c31af7Sopenharmony_ci const vk::VkOffset3D zeroOffset = { 0, 0, 0 }; 425e5c31af7Sopenharmony_ci const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), 426e5c31af7Sopenharmony_ci vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT); 427e5c31af7Sopenharmony_ci 428e5c31af7Sopenharmony_ci if (!tcu::fuzzyCompare(log, "Result", "Image comparison result", 429e5c31af7Sopenharmony_ci referenceFrame.getLevel(0), renderedFrame, 0.05f, 430e5c31af7Sopenharmony_ci tcu::COMPARE_LOG_RESULT)) 431e5c31af7Sopenharmony_ci { 432e5c31af7Sopenharmony_ci return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed"); 433e5c31af7Sopenharmony_ci } 434e5c31af7Sopenharmony_ci 435e5c31af7Sopenharmony_ci return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed"); 436e5c31af7Sopenharmony_ci } 437e5c31af7Sopenharmony_ci}; 438e5c31af7Sopenharmony_ci 439e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 440e5c31af7Sopenharmony_civoid checkMeshShaderSupport (Context& context) 441e5c31af7Sopenharmony_ci{ 442e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_EXT_mesh_shader"); 443e5c31af7Sopenharmony_ci} 444e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 445e5c31af7Sopenharmony_ci 446e5c31af7Sopenharmony_civoid checkNothing (Context&) 447e5c31af7Sopenharmony_ci{ 448e5c31af7Sopenharmony_ci} 449e5c31af7Sopenharmony_ci 450e5c31af7Sopenharmony_ci} //anonymous 451e5c31af7Sopenharmony_ci 452e5c31af7Sopenharmony_ci// General tests for dynamic states 453e5c31af7Sopenharmony_ciDynamicStateGeneralTests::DynamicStateGeneralTests (tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType) 454e5c31af7Sopenharmony_ci : TestCaseGroup (testCtx, "general_state") 455e5c31af7Sopenharmony_ci , m_pipelineConstructionType (pipelineConstructionType) 456e5c31af7Sopenharmony_ci{ 457e5c31af7Sopenharmony_ci /* Left blank on purpose */ 458e5c31af7Sopenharmony_ci} 459e5c31af7Sopenharmony_ci 460e5c31af7Sopenharmony_ciDynamicStateGeneralTests::~DynamicStateGeneralTests (void) {} 461e5c31af7Sopenharmony_ci 462e5c31af7Sopenharmony_civoid DynamicStateGeneralTests::init (void) 463e5c31af7Sopenharmony_ci{ 464e5c31af7Sopenharmony_ci ShaderMap basePaths; 465e5c31af7Sopenharmony_ci basePaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag"; 466e5c31af7Sopenharmony_ci basePaths[glu::SHADERTYPE_MESH] = nullptr; 467e5c31af7Sopenharmony_ci basePaths[glu::SHADERTYPE_VERTEX] = nullptr; 468e5c31af7Sopenharmony_ci 469e5c31af7Sopenharmony_ci for (int i = 0; i < 2; ++i) 470e5c31af7Sopenharmony_ci { 471e5c31af7Sopenharmony_ci const bool isMesh = (i > 0); 472e5c31af7Sopenharmony_ci ShaderMap shaderPaths (basePaths); 473e5c31af7Sopenharmony_ci std::string nameSuffix; 474e5c31af7Sopenharmony_ci FunctionSupport0::Function checkSupportFunc; 475e5c31af7Sopenharmony_ci 476e5c31af7Sopenharmony_ci if (isMesh) 477e5c31af7Sopenharmony_ci { 478e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 479e5c31af7Sopenharmony_ci shaderPaths[glu::SHADERTYPE_MESH] = "vulkan/dynamic_state/VertexFetch.mesh"; 480e5c31af7Sopenharmony_ci nameSuffix = "_mesh"; 481e5c31af7Sopenharmony_ci checkSupportFunc = checkMeshShaderSupport; 482e5c31af7Sopenharmony_ci#else 483e5c31af7Sopenharmony_ci continue; 484e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 485e5c31af7Sopenharmony_ci } 486e5c31af7Sopenharmony_ci else 487e5c31af7Sopenharmony_ci { 488e5c31af7Sopenharmony_ci shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert"; 489e5c31af7Sopenharmony_ci checkSupportFunc = checkNothing; 490e5c31af7Sopenharmony_ci } 491e5c31af7Sopenharmony_ci 492e5c31af7Sopenharmony_ci // Perform multiple draws with different VP states (scissor test) 493e5c31af7Sopenharmony_ci addChild(new InstanceFactory<StateSwitchTestInstance, FunctionSupport0>(m_testCtx, "state_switch" + nameSuffix, m_pipelineConstructionType, shaderPaths, checkSupportFunc)); 494e5c31af7Sopenharmony_ci // Check if binding order is not important for pipeline configuration 495e5c31af7Sopenharmony_ci addChild(new InstanceFactory<BindOrderTestInstance, FunctionSupport0>(m_testCtx, "bind_order" + nameSuffix, m_pipelineConstructionType, shaderPaths, checkSupportFunc)); 496e5c31af7Sopenharmony_ci if (!isMesh) { 497e5c31af7Sopenharmony_ci // Check if bound states are persistent across pipelines 498e5c31af7Sopenharmony_ci addChild(new InstanceFactory<StatePersistenceTestInstance>(m_testCtx, "state_persistence" + nameSuffix, m_pipelineConstructionType, shaderPaths)); 499e5c31af7Sopenharmony_ci } 500e5c31af7Sopenharmony_ci } 501e5c31af7Sopenharmony_ci} 502e5c31af7Sopenharmony_ci 503e5c31af7Sopenharmony_ci} // DynamicState 504e5c31af7Sopenharmony_ci} // vkt 505