1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2015 The Khronos Group Inc. 6 * Copyright (c) 2015 Intel Corporation 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 * 20 *//*! 21 * \file 22 * \brief Dynamic Raster State Tests 23 *//*--------------------------------------------------------------------*/ 24 25 #include "vktDynamicStateRSTests.hpp" 26 27 #include "vktDynamicStateBaseClass.hpp" 28 #include "vktDynamicStateTestCaseUtil.hpp" 29 30 #include "vkImageUtil.hpp" 31 32 #include "tcuTextureUtil.hpp" 33 #include "tcuImageCompare.hpp" 34 #include "tcuRGBA.hpp" 35 36 #include "deMath.h" 37 38 namespace vkt 39 { 40 namespace DynamicState 41 { 42 namespace 43 { 44 45 class DepthBiasBaseCase : public TestInstance 46 { 47 public: 48 DepthBiasBaseCase (Context& context, const char* vertexShaderName, const char* fragmentShaderName) 49 : TestInstance (context) 50 , m_colorAttachmentFormat (vk::VK_FORMAT_R8G8B8A8_UNORM) 51 , m_topology (vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP) 52 , m_vk (context.getDeviceInterface()) 53 , m_vertexShaderName (vertexShaderName) 54 , m_fragmentShaderName (fragmentShaderName) 55 { 56 } 57 58 protected: 59 60 enum 61 { 62 WIDTH = 128, 63 HEIGHT = 128 64 }; 65 66 vk::VkFormat m_colorAttachmentFormat; 67 vk::VkFormat m_depthStencilAttachmentFormat; 68 69 vk::VkPrimitiveTopology m_topology; 70 71 const vk::DeviceInterface& m_vk; 72 73 vk::Move<vk::VkPipeline> m_pipeline; 74 vk::Move<vk::VkPipelineLayout> m_pipelineLayout; 75 76 de::SharedPtr<Image> m_colorTargetImage; 77 vk::Move<vk::VkImageView> m_colorTargetView; 78 79 de::SharedPtr<Image> m_depthStencilImage; 80 vk::Move<vk::VkImageView> m_attachmentView; 81 82 PipelineCreateInfo::VertexInputState m_vertexInputState; 83 de::SharedPtr<Buffer> m_vertexBuffer; 84 85 vk::Move<vk::VkCommandPool> m_cmdPool; 86 vk::Move<vk::VkCommandBuffer> m_cmdBuffer; 87 88 vk::Move<vk::VkFramebuffer> m_framebuffer; 89 vk::Move<vk::VkRenderPass> m_renderPass; 90 91 std::string m_vertexShaderName; 92 std::string m_fragmentShaderName; 93 94 std::vector<PositionColorVertex> m_data; 95 96 PipelineCreateInfo::DepthStencilState m_depthStencilState; 97 98 void initialize (void) 99 { 100 const vk::VkDevice device = m_context.getDevice(); 101 102 vk::VkFormatProperties formatProperties; 103 // check for VK_FORMAT_D24_UNORM_S8_UINT support 104 m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), vk::VK_FORMAT_D24_UNORM_S8_UINT, &formatProperties); 105 if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) 106 { 107 m_depthStencilAttachmentFormat = vk::VK_FORMAT_D24_UNORM_S8_UINT; 108 } 109 else 110 { 111 // check for VK_FORMAT_D32_SFLOAT_S8_UINT support 112 m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), vk::VK_FORMAT_D32_SFLOAT_S8_UINT, &formatProperties); 113 if (formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) 114 { 115 m_depthStencilAttachmentFormat = vk::VK_FORMAT_D32_SFLOAT_S8_UINT; 116 } 117 else 118 throw tcu::NotSupportedError("No valid depth stencil attachment available"); 119 } 120 121 const PipelineLayoutCreateInfo pipelineLayoutCreateInfo; 122 m_pipelineLayout = vk::createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo); 123 124 const vk::Unique<vk::VkShaderModule> vs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0)); 125 const vk::Unique<vk::VkShaderModule> fs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0)); 126 127 const vk::VkExtent3D imageExtent = { WIDTH, HEIGHT, 1 }; 128 ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL, 129 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT); 130 131 m_colorTargetImage = Image::createAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator()); 132 133 const ImageCreateInfo depthStencilImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_depthStencilAttachmentFormat, imageExtent, 134 1, 1, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL, 135 vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT); 136 137 m_depthStencilImage = Image::createAndAlloc(m_vk, device, depthStencilImageCreateInfo, m_context.getDefaultAllocator()); 138 139 const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_colorAttachmentFormat); 140 m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo); 141 142 const ImageViewCreateInfo attachmentViewInfo(m_depthStencilImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, m_depthStencilAttachmentFormat); 143 m_attachmentView = vk::createImageView(m_vk, device, &attachmentViewInfo); 144 145 RenderPassCreateInfo renderPassCreateInfo; 146 renderPassCreateInfo.addAttachment(AttachmentDescription(m_colorAttachmentFormat, 147 vk::VK_SAMPLE_COUNT_1_BIT, 148 vk::VK_ATTACHMENT_LOAD_OP_LOAD, 149 vk::VK_ATTACHMENT_STORE_OP_STORE, 150 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, 151 vk::VK_ATTACHMENT_STORE_OP_STORE, 152 vk::VK_IMAGE_LAYOUT_GENERAL, 153 vk::VK_IMAGE_LAYOUT_GENERAL)); 154 155 renderPassCreateInfo.addAttachment(AttachmentDescription(m_depthStencilAttachmentFormat, 156 vk::VK_SAMPLE_COUNT_1_BIT, 157 vk::VK_ATTACHMENT_LOAD_OP_LOAD, 158 vk::VK_ATTACHMENT_STORE_OP_STORE, 159 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, 160 vk::VK_ATTACHMENT_STORE_OP_STORE, 161 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 162 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); 163 164 const vk::VkAttachmentReference colorAttachmentReference = 165 { 166 0, 167 vk::VK_IMAGE_LAYOUT_GENERAL 168 }; 169 170 const vk::VkAttachmentReference depthAttachmentReference = 171 { 172 1, 173 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL 174 }; 175 176 renderPassCreateInfo.addSubpass(SubpassDescription(vk::VK_PIPELINE_BIND_POINT_GRAPHICS, 177 0, 178 0, 179 DE_NULL, 180 1, 181 &colorAttachmentReference, 182 DE_NULL, 183 depthAttachmentReference, 184 0, 185 DE_NULL)); 186 187 m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo); 188 189 const vk::VkVertexInputBindingDescription vertexInputBindingDescription = 190 { 191 0, 192 (deUint32)sizeof(tcu::Vec4) * 2, 193 vk::VK_VERTEX_INPUT_RATE_VERTEX, 194 }; 195 196 const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] = 197 { 198 { 199 0u, 200 0u, 201 vk::VK_FORMAT_R32G32B32A32_SFLOAT, 202 0u 203 }, 204 { 205 1u, 206 0u, 207 vk::VK_FORMAT_R32G32B32A32_SFLOAT, 208 (deUint32)(sizeof(float)* 4), 209 } 210 }; 211 212 m_vertexInputState = PipelineCreateInfo::VertexInputState(1, 213 &vertexInputBindingDescription, 214 2, 215 vertexInputAttributeDescriptions); 216 217 const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState; 218 219 PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, 0); 220 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT)); 221 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT)); 222 pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState)); 223 pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_topology)); 224 pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState)); 225 pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1)); 226 pipelineCreateInfo.addState(m_depthStencilState); 227 pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState()); 228 pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState()); 229 pipelineCreateInfo.addState(PipelineCreateInfo::DynamicState()); 230 231 m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo); 232 233 std::vector<vk::VkImageView> attachments(2); 234 attachments[0] = *m_colorTargetView; 235 attachments[1] = *m_attachmentView; 236 237 const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1); 238 239 m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo); 240 241 const vk::VkDeviceSize dataSize = m_data.size() * sizeof(PositionColorVertex); 242 m_vertexBuffer = Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize, 243 vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), 244 m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible); 245 246 deUint8* ptr = reinterpret_cast<unsigned char *>(m_vertexBuffer->getBoundMemory().getHostPtr()); 247 deMemcpy(ptr, &m_data[0], static_cast<size_t>(dataSize)); 248 249 vk::flushMappedMemoryRange(m_vk, device, 250 m_vertexBuffer->getBoundMemory().getMemory(), 251 m_vertexBuffer->getBoundMemory().getOffset(), 252 sizeof(dataSize)); 253 254 const CmdPoolCreateInfo cmdPoolCreateInfo(m_context.getUniversalQueueFamilyIndex()); 255 m_cmdPool = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo); 256 257 const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo = 258 { 259 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 260 DE_NULL, // const void* pNext; 261 *m_cmdPool, // VkCommandPool commandPool; 262 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 263 1u, // deUint32 bufferCount; 264 }; 265 m_cmdBuffer = vk::allocateCommandBuffer(m_vk, device, &cmdBufferAllocateInfo); 266 } 267 268 virtual tcu::TestStatus iterate (void) 269 { 270 DE_ASSERT(false); 271 return tcu::TestStatus::fail("Should reimplement iterate() method"); 272 } 273 274 void beginRenderPass (void) 275 { 276 const vk::VkClearColorValue clearColor = { { 0.0f, 0.0f, 0.0f, 1.0f } }; 277 beginRenderPassWithClearColor(clearColor); 278 } 279 280 void beginRenderPassWithClearColor (const vk::VkClearColorValue &clearColor) 281 { 282 const CmdBufferBeginInfo beginInfo; 283 m_vk.beginCommandBuffer(*m_cmdBuffer, &beginInfo); 284 285 initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL); 286 initialTransitionDepthStencil2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, vk::VK_ACCESS_TRANSFER_WRITE_BIT); 287 288 const ImageSubresourceRange subresourceRangeImage(vk::VK_IMAGE_ASPECT_COLOR_BIT); 289 m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(), 290 vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRangeImage); 291 292 const vk::VkClearDepthStencilValue depthStencilClearValue = { 0.0f, 0 }; 293 294 const ImageSubresourceRange subresourceRangeDepthStencil[2] = { vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_ASPECT_STENCIL_BIT }; 295 296 m_vk.cmdClearDepthStencilImage(*m_cmdBuffer, m_depthStencilImage->object(), 297 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencilClearValue, 2, subresourceRangeDepthStencil); 298 299 const vk::VkMemoryBarrier memBarrier = 300 { 301 vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER, 302 DE_NULL, 303 vk::VK_ACCESS_TRANSFER_WRITE_BIT, 304 vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 305 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT 306 }; 307 308 m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 309 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | 310 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 311 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL); 312 313 const vk::VkRect2D renderArea = { { 0, 0 }, { WIDTH, HEIGHT } }; 314 const RenderPassBeginInfo renderPassBegin(*m_renderPass, *m_framebuffer, renderArea); 315 316 transition2DImage(m_vk, *m_cmdBuffer, m_depthStencilImage->object(), vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT); 317 318 m_vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBegin, vk::VK_SUBPASS_CONTENTS_INLINE); 319 } 320 321 void setDynamicViewportState (const deUint32 width, const deUint32 height) 322 { 323 vk::VkViewport viewport; 324 viewport.x = 0; 325 viewport.y = 0; 326 viewport.width = static_cast<float>(width); 327 viewport.height = static_cast<float>(height); 328 viewport.minDepth = 0.0f; 329 viewport.maxDepth = 1.0f; 330 331 m_vk.cmdSetViewport(*m_cmdBuffer, 0, 1, &viewport); 332 333 vk::VkRect2D scissor; 334 scissor.offset.x = 0; 335 scissor.offset.y = 0; 336 scissor.extent.width = width; 337 scissor.extent.height = height; 338 m_vk.cmdSetScissor(*m_cmdBuffer, 0, 1, &scissor); 339 } 340 341 void setDynamicViewportState (const deUint32 viewportCount, const vk::VkViewport* pViewports, const vk::VkRect2D* pScissors) 342 { 343 m_vk.cmdSetViewport(*m_cmdBuffer, 0, viewportCount, pViewports); 344 m_vk.cmdSetScissor(*m_cmdBuffer, 0, viewportCount, pScissors); 345 } 346 347 void setDynamicRasterizationState (const float lineWidth = 1.0f, 348 const float depthBiasConstantFactor = 0.0f, 349 const float depthBiasClamp = 0.0f, 350 const float depthBiasSlopeFactor = 0.0f) 351 { 352 m_vk.cmdSetLineWidth(*m_cmdBuffer, lineWidth); 353 m_vk.cmdSetDepthBias(*m_cmdBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor); 354 } 355 356 void setDynamicBlendState (const float const1 = 0.0f, const float const2 = 0.0f, 357 const float const3 = 0.0f, const float const4 = 0.0f) 358 { 359 float blendConstantsants[4] = { const1, const2, const3, const4 }; 360 m_vk.cmdSetBlendConstants(*m_cmdBuffer, blendConstantsants); 361 } 362 363 void setDynamicDepthStencilState (const float minDepthBounds = -1.0f, const float maxDepthBounds = 1.0f, 364 const deUint32 stencilFrontCompareMask = 0xffffffffu, const deUint32 stencilFrontWriteMask = 0xffffffffu, 365 const deUint32 stencilFrontReference = 0, const deUint32 stencilBackCompareMask = 0xffffffffu, 366 const deUint32 stencilBackWriteMask = 0xffffffffu, const deUint32 stencilBackReference = 0) 367 { 368 m_vk.cmdSetDepthBounds(*m_cmdBuffer, minDepthBounds, maxDepthBounds); 369 m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontCompareMask); 370 m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontWriteMask); 371 m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, stencilFrontReference); 372 m_vk.cmdSetStencilCompareMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackCompareMask); 373 m_vk.cmdSetStencilWriteMask(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackWriteMask); 374 m_vk.cmdSetStencilReference(*m_cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, stencilBackReference); 375 } 376 }; 377 378 class DepthBiasParamTestInstance : public DepthBiasBaseCase 379 { 380 public: 381 DepthBiasParamTestInstance (Context& context, ShaderMap shaders) 382 : DepthBiasBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT]) 383 { 384 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec())); 385 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec())); 386 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec())); 387 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::blue().toVec())); 388 389 m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec())); 390 m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec())); 391 m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec())); 392 m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, -0.5f, 1.0f, 1.0f), tcu::RGBA::green().toVec())); 393 394 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec())); 395 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec())); 396 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec())); 397 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.5f, 1.0f), tcu::RGBA::red().toVec())); 398 399 // enable depth test 400 m_depthStencilState = PipelineCreateInfo::DepthStencilState( 401 vk::VK_TRUE, vk::VK_TRUE, vk::VK_COMPARE_OP_GREATER_OR_EQUAL); 402 403 DepthBiasBaseCase::initialize(); 404 } 405 406 virtual tcu::TestStatus iterate (void) 407 { 408 tcu::TestLog &log = m_context.getTestContext().getLog(); 409 const vk::VkQueue queue = m_context.getUniversalQueue(); 410 411 beginRenderPass(); 412 413 // set states here 414 setDynamicViewportState(WIDTH, HEIGHT); 415 setDynamicBlendState(); 416 setDynamicDepthStencilState(); 417 418 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline); 419 420 const vk::VkDeviceSize vertexBufferOffset = 0; 421 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object(); 422 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset); 423 424 setDynamicRasterizationState(1.0f, 0.0f); 425 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0); 426 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0); 427 428 setDynamicRasterizationState(1.0f, -1.0f); 429 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 8, 0); 430 431 m_vk.cmdEndRenderPass(*m_cmdBuffer); 432 m_vk.endCommandBuffer(*m_cmdBuffer); 433 434 vk::VkSubmitInfo submitInfo = 435 { 436 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 437 DE_NULL, // const void* pNext; 438 0, // deUint32 waitSemaphoreCount; 439 DE_NULL, // const VkSemaphore* pWaitSemaphores; 440 (const vk::VkPipelineStageFlags*)DE_NULL, 441 1, // deUint32 commandBufferCount; 442 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 443 0, // deUint32 signalSemaphoreCount; 444 DE_NULL // const VkSemaphore* pSignalSemaphores; 445 }; 446 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL); 447 448 // validation 449 { 450 VK_CHECK(m_vk.queueWaitIdle(queue)); 451 452 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT)); 453 referenceFrame.allocLevel(0); 454 455 const deInt32 frameWidth = referenceFrame.getWidth(); 456 const deInt32 frameHeight = referenceFrame.getHeight(); 457 458 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 459 460 for (int y = 0; y < frameHeight; y++) 461 { 462 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f; 463 464 for (int x = 0; x < frameWidth; x++) 465 { 466 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f; 467 468 if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f) 469 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y); 470 else 471 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y); 472 } 473 } 474 475 const vk::VkOffset3D zeroOffset = { 0, 0, 0 }; 476 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), 477 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT); 478 479 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result", 480 referenceFrame.getLevel(0), renderedFrame, 0.05f, 481 tcu::COMPARE_LOG_RESULT)) 482 { 483 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed"); 484 } 485 486 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed"); 487 } 488 } 489 }; 490 491 class DepthBiasClampParamTestInstance : public DepthBiasBaseCase 492 { 493 public: 494 DepthBiasClampParamTestInstance (Context& context, ShaderMap shaders) 495 : DepthBiasBaseCase (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT]) 496 { 497 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec())); 498 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec())); 499 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec())); 500 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f), tcu::RGBA::blue().toVec())); 501 502 m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, 0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec())); 503 m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, 0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec())); 504 m_data.push_back(PositionColorVertex(tcu::Vec4(-0.5f, -0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec())); 505 m_data.push_back(PositionColorVertex(tcu::Vec4(0.5f, -0.5f, 0.01f, 1.0f), tcu::RGBA::green().toVec())); 506 507 // enable depth test 508 m_depthStencilState = PipelineCreateInfo::DepthStencilState(vk::VK_TRUE, vk::VK_TRUE, vk::VK_COMPARE_OP_GREATER_OR_EQUAL); 509 510 DepthBiasBaseCase::initialize(); 511 } 512 513 virtual tcu::TestStatus iterate (void) 514 { 515 tcu::TestLog &log = m_context.getTestContext().getLog(); 516 const vk::VkQueue queue = m_context.getUniversalQueue(); 517 518 beginRenderPass(); 519 520 // set states here 521 setDynamicViewportState(WIDTH, HEIGHT); 522 setDynamicBlendState(); 523 setDynamicDepthStencilState(); 524 525 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline); 526 527 const vk::VkDeviceSize vertexBufferOffset = 0; 528 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object(); 529 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset); 530 531 setDynamicRasterizationState(1.0f, 1000.0f, 0.005f); 532 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0); 533 534 setDynamicRasterizationState(1.0f, 0.0f); 535 m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 4, 0); 536 537 m_vk.cmdEndRenderPass(*m_cmdBuffer); 538 m_vk.endCommandBuffer(*m_cmdBuffer); 539 540 vk::VkSubmitInfo submitInfo = 541 { 542 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 543 DE_NULL, // const void* pNext; 544 0, // deUint32 waitSemaphoreCount; 545 DE_NULL, // const VkSemaphore* pWaitSemaphores; 546 (const vk::VkPipelineStageFlags*)DE_NULL, 547 1, // deUint32 commandBufferCount; 548 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 549 0, // deUint32 signalSemaphoreCount; 550 DE_NULL // const VkSemaphore* pSignalSemaphores; 551 }; 552 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL); 553 554 // validation 555 { 556 VK_CHECK(m_vk.queueWaitIdle(queue)); 557 558 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT)); 559 referenceFrame.allocLevel(0); 560 561 const deInt32 frameWidth = referenceFrame.getWidth(); 562 const deInt32 frameHeight = referenceFrame.getHeight(); 563 564 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 565 566 for (int y = 0; y < frameHeight; y++) 567 { 568 float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f; 569 570 for (int x = 0; x < frameWidth; x++) 571 { 572 float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f; 573 574 if (xCoord >= -0.5f && xCoord <= 0.5f && yCoord >= -0.5f && yCoord <= 0.5f) 575 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y); 576 else 577 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y); 578 } 579 } 580 581 const vk::VkOffset3D zeroOffset = { 0, 0, 0 }; 582 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), 583 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT); 584 585 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result", 586 referenceFrame.getLevel(0), renderedFrame, 0.05f, 587 tcu::COMPARE_LOG_RESULT)) 588 { 589 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed"); 590 } 591 592 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed"); 593 } 594 } 595 }; 596 597 class LineWidthParamTestInstance : public DynamicStateBaseClass 598 { 599 public: 600 LineWidthParamTestInstance (Context& context, ShaderMap shaders) 601 : DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT]) 602 { 603 // Check if line width test is supported 604 { 605 const vk::VkPhysicalDeviceFeatures& deviceFeatures = m_context.getDeviceFeatures(); 606 607 if (!deviceFeatures.wideLines) 608 throw tcu::NotSupportedError("Line width test is unsupported"); 609 } 610 611 m_topology = vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST; 612 613 m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 0.0f, 0.0f, 1.0f), tcu::RGBA::green().toVec())); 614 m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::RGBA::green().toVec())); 615 616 DynamicStateBaseClass::initialize(); 617 } 618 619 virtual tcu::TestStatus iterate (void) 620 { 621 tcu::TestLog &log = m_context.getTestContext().getLog(); 622 const vk::VkQueue queue = m_context.getUniversalQueue(); 623 624 beginRenderPass(); 625 626 // set states here 627 vk::VkPhysicalDeviceProperties deviceProperties; 628 m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties); 629 630 setDynamicViewportState(WIDTH, HEIGHT); 631 setDynamicBlendState(); 632 setDynamicDepthStencilState(); 633 setDynamicRasterizationState(deFloatFloor(deviceProperties.limits.lineWidthRange[1])); 634 635 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline); 636 637 const vk::VkDeviceSize vertexBufferOffset = 0; 638 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object(); 639 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset); 640 641 m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0); 642 643 m_vk.cmdEndRenderPass(*m_cmdBuffer); 644 m_vk.endCommandBuffer(*m_cmdBuffer); 645 646 vk::VkSubmitInfo submitInfo = 647 { 648 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 649 DE_NULL, // const void* pNext; 650 0, // deUint32 waitSemaphoreCount; 651 DE_NULL, // const VkSemaphore* pWaitSemaphores; 652 (const vk::VkPipelineStageFlags*)DE_NULL, 653 1, // deUint32 commandBufferCount; 654 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 655 0, // deUint32 signalSemaphoreCount; 656 DE_NULL // const VkSemaphore* pSignalSemaphores; 657 }; 658 m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL); 659 660 // validation 661 { 662 VK_CHECK(m_vk.queueWaitIdle(queue)); 663 664 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT)); 665 referenceFrame.allocLevel(0); 666 667 const deInt32 frameWidth = referenceFrame.getWidth(); 668 const deInt32 frameHeight = referenceFrame.getHeight(); 669 670 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 671 672 for (int y = 0; y < frameHeight; y++) 673 { 674 float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f; 675 676 for (int x = 0; x < frameWidth; x++) 677 { 678 float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f; 679 float lineHalfWidth = (float)(deFloor(deviceProperties.limits.lineWidthRange[1]) / frameHeight); 680 681 if (xCoord >= -1.0f && xCoord <= 1.0f && yCoord >= -lineHalfWidth && yCoord <= lineHalfWidth) 682 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y); 683 } 684 } 685 686 const vk::VkOffset3D zeroOffset = { 0, 0, 0 }; 687 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), 688 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, 689 vk::VK_IMAGE_ASPECT_COLOR_BIT); 690 691 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result", 692 referenceFrame.getLevel(0), renderedFrame, 0.05f, 693 tcu::COMPARE_LOG_RESULT)) 694 { 695 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed"); 696 } 697 698 return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed"); 699 } 700 } 701 }; 702 703 } //anonymous 704 705 DynamicStateRSTests::DynamicStateRSTests (tcu::TestContext& testCtx) 706 : TestCaseGroup (testCtx, "rs_state", "Tests for rasterizer state") 707 { 708 /* Left blank on purpose */ 709 } 710 711 DynamicStateRSTests::~DynamicStateRSTests () 712 { 713 } 714 715 void DynamicStateRSTests::init (void) 716 { 717 ShaderMap shaderPaths; 718 shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert"; 719 shaderPaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag"; 720 721 addChild(new InstanceFactory<DepthBiasParamTestInstance>(m_testCtx, "depth_bias", "Test depth bias functionality", shaderPaths)); 722 addChild(new InstanceFactory<DepthBiasClampParamTestInstance>(m_testCtx, "depth_bias_clamp", "Test depth bias clamp functionality", shaderPaths)); 723 addChild(new InstanceFactory<LineWidthParamTestInstance>(m_testCtx, "line_width", "Draw a line with width set to max defined by physical device", shaderPaths)); 724 } 725 726 } // DynamicState 727 } // vkt 728