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