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 Draw Indexed Tests 23 *//*--------------------------------------------------------------------*/ 24 25#include "vktDrawIndexedTest.hpp" 26 27#include "vktTestCaseUtil.hpp" 28#include "vktDrawTestCaseUtil.hpp" 29 30#include "vktDrawBaseClass.hpp" 31 32#include "tcuTestLog.hpp" 33#include "tcuResource.hpp" 34#include "tcuImageCompare.hpp" 35#include "tcuTextureUtil.hpp" 36#include "tcuRGBA.hpp" 37 38#include "vkDefs.hpp" 39 40enum 41{ 42 VERTEX_OFFSET = 13 43}; 44 45namespace vkt 46{ 47namespace Draw 48{ 49namespace 50{ 51class DrawIndexed : public DrawTestsBaseClass 52{ 53public: 54 typedef TestSpecBase TestSpec; 55 56 DrawIndexed (Context &context, TestSpec testSpec); 57 virtual tcu::TestStatus iterate (void); 58protected: 59 std::vector<deUint32> m_indexes; 60 de::SharedPtr<Buffer> m_indexBuffer; 61}; 62 63class DrawInstancedIndexed : public DrawIndexed 64{ 65public: 66 DrawInstancedIndexed (Context &context, TestSpec testSpec); 67 virtual tcu::TestStatus iterate (void); 68}; 69 70DrawIndexed::DrawIndexed (Context &context, TestSpec testSpec) 71 : DrawTestsBaseClass(context, testSpec.shaders[glu::SHADERTYPE_VERTEX], testSpec.shaders[glu::SHADERTYPE_FRAGMENT], testSpec.topology) 72{ 73 switch (m_topology) 74 { 75 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: 76 m_indexes.push_back(0); 77 m_indexes.push_back(0); 78 m_indexes.push_back(2); 79 m_indexes.push_back(0); 80 m_indexes.push_back(6); 81 m_indexes.push_back(6); 82 m_indexes.push_back(0); 83 m_indexes.push_back(7); 84 break; 85 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: 86 m_indexes.push_back(0); 87 m_indexes.push_back(0); 88 m_indexes.push_back(2); 89 m_indexes.push_back(0); 90 m_indexes.push_back(6); 91 m_indexes.push_back(5); 92 m_indexes.push_back(0); 93 m_indexes.push_back(7); 94 break; 95 96 case vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST: 97 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST: 98 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: 99 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: 100 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: 101 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY: 102 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: 103 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY: 104 case vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: 105 case vk::VK_PRIMITIVE_TOPOLOGY_LAST: 106 DE_FATAL("Topology not implemented"); 107 break; 108 default: 109 DE_FATAL("Unknown topology"); 110 break; 111 } 112 113 for (int unusedIdx = 0; unusedIdx < VERTEX_OFFSET; unusedIdx++) 114 { 115 m_data.push_back(VertexElementData(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), -1)); 116 } 117 118 int vertexIndex = VERTEX_OFFSET; 119 120 m_data.push_back(VertexElementData(tcu::Vec4( -0.3f, 0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), vertexIndex++)); 121 m_data.push_back(VertexElementData(tcu::Vec4( -1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), vertexIndex++)); 122 m_data.push_back(VertexElementData(tcu::Vec4( -0.3f, -0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), vertexIndex++)); 123 m_data.push_back(VertexElementData(tcu::Vec4( 1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), vertexIndex++)); 124 m_data.push_back(VertexElementData(tcu::Vec4( -0.3f, -0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), vertexIndex++)); 125 m_data.push_back(VertexElementData(tcu::Vec4( 0.3f, 0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), vertexIndex++)); 126 m_data.push_back(VertexElementData(tcu::Vec4( 0.3f, -0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), vertexIndex++)); 127 m_data.push_back(VertexElementData(tcu::Vec4( 0.3f, 0.3f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), vertexIndex++)); 128 129 m_data.push_back(VertexElementData(tcu::Vec4( -1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec(), -1)); 130 131 initialize(); 132}; 133 134tcu::TestStatus DrawIndexed::iterate (void) 135{ 136 tcu::TestLog &log = m_context.getTestContext().getLog(); 137 const vk::VkQueue queue = m_context.getUniversalQueue(); 138 139 beginRenderPass(); 140 141 const vk::VkDeviceSize dataSize = m_indexes.size() * sizeof(deUint32); 142 m_indexBuffer = Buffer::createAndAlloc( m_vk, m_context.getDevice(), 143 BufferCreateInfo(dataSize, 144 vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT), 145 m_context.getDefaultAllocator(), 146 vk::MemoryRequirement::HostVisible); 147 148 deUint8* ptr = reinterpret_cast<deUint8*>(m_indexBuffer->getBoundMemory().getHostPtr()); 149 150 deMemcpy(ptr, &m_indexes[0], static_cast<size_t>(dataSize)); 151 152 vk::flushMappedMemoryRange(m_vk, m_context.getDevice(), 153 m_indexBuffer->getBoundMemory().getMemory(), 154 m_indexBuffer->getBoundMemory().getOffset(), 155 dataSize); 156 157 const vk::VkDeviceSize vertexBufferOffset = 0; 158 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object(); 159 const vk::VkBuffer indexBuffer = m_indexBuffer->object(); 160 161 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset); 162 m_vk.cmdBindIndexBuffer(*m_cmdBuffer, indexBuffer, 0, vk::VK_INDEX_TYPE_UINT32); 163 164 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline); 165 166 m_vk.cmdDrawIndexed(*m_cmdBuffer, 6, 1, 2, VERTEX_OFFSET, 0); 167 168 m_vk.cmdEndRenderPass(*m_cmdBuffer); 169 m_vk.endCommandBuffer(*m_cmdBuffer); 170 171 vk::VkSubmitInfo submitInfo = 172 { 173 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 174 DE_NULL, // const void* pNext; 175 0, // deUint32 waitSemaphoreCount; 176 DE_NULL, // const VkSemaphore* pWaitSemaphores; 177 (const vk::VkPipelineStageFlags*)DE_NULL, 178 1, // deUint32 commandBufferCount; 179 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 180 0, // deUint32 signalSemaphoreCount; 181 DE_NULL // const VkSemaphore* pSignalSemaphores; 182 }; 183 184 VK_CHECK(m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL)); 185 186 VK_CHECK(m_vk.queueWaitIdle(queue)); 187 188 // Validation 189 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT)); 190 referenceFrame.allocLevel(0); 191 192 const deInt32 frameWidth = referenceFrame.getWidth(); 193 const deInt32 frameHeight = referenceFrame.getHeight(); 194 195 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 196 197 ReferenceImageCoordinates refCoords; 198 199 for (int y = 0; y < frameHeight; y++) 200 { 201 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f; 202 203 for (int x = 0; x < frameWidth; x++) 204 { 205 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f; 206 207 if ((yCoord >= refCoords.bottom && 208 yCoord <= refCoords.top && 209 xCoord >= refCoords.left && 210 xCoord <= refCoords.right)) 211 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y); 212 } 213 } 214 215 const vk::VkOffset3D zeroOffset = { 0, 0, 0 }; 216 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), 217 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT); 218 219 qpTestResult res = QP_TEST_RESULT_PASS; 220 221 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result", 222 referenceFrame.getLevel(0), renderedFrame, 0.05f, 223 tcu::COMPARE_LOG_RESULT)) { 224 res = QP_TEST_RESULT_FAIL; 225 } 226 227 return tcu::TestStatus(res, qpGetTestResultName(res)); 228}; 229 230DrawInstancedIndexed::DrawInstancedIndexed (Context &context, TestSpec testSpec) 231 : DrawIndexed (context, testSpec) 232{ 233} 234 235tcu::TestStatus DrawInstancedIndexed::iterate (void) 236{ 237 tcu::TestLog &log = m_context.getTestContext().getLog(); 238 const vk::VkQueue queue = m_context.getUniversalQueue(); 239 240 beginRenderPass(); 241 242 const vk::VkDeviceSize dataSize = m_indexes.size() * sizeof(deUint32); 243 m_indexBuffer = Buffer::createAndAlloc( m_vk, m_context.getDevice(), 244 BufferCreateInfo(dataSize, 245 vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT), 246 m_context.getDefaultAllocator(), 247 vk::MemoryRequirement::HostVisible); 248 249 deUint8* ptr = reinterpret_cast<deUint8*>(m_indexBuffer->getBoundMemory().getHostPtr()); 250 251 deMemcpy(ptr, &m_indexes[0], static_cast<size_t>(dataSize)); 252 vk::flushMappedMemoryRange(m_vk, m_context.getDevice(), 253 m_indexBuffer->getBoundMemory().getMemory(), 254 m_indexBuffer->getBoundMemory().getOffset(), 255 dataSize); 256 257 const vk::VkDeviceSize vertexBufferOffset = 0; 258 const vk::VkBuffer vertexBuffer = m_vertexBuffer->object(); 259 const vk::VkBuffer indexBuffer = m_indexBuffer->object(); 260 261 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset); 262 m_vk.cmdBindIndexBuffer(*m_cmdBuffer, indexBuffer, 0, vk::VK_INDEX_TYPE_UINT32); 263 m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline); 264 265 switch (m_topology) 266 { 267 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: 268 m_vk.cmdDrawIndexed(*m_cmdBuffer, 6, 4, 2, VERTEX_OFFSET, 2); 269 break; 270 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: 271 m_vk.cmdDrawIndexed(*m_cmdBuffer, 4, 4, 2, VERTEX_OFFSET, 2); 272 break; 273 case vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST: 274 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST: 275 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: 276 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: 277 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: 278 case vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY: 279 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: 280 case vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY: 281 case vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: 282 case vk::VK_PRIMITIVE_TOPOLOGY_LAST: 283 DE_FATAL("Topology not implemented"); 284 break; 285 default: 286 DE_FATAL("Unknown topology"); 287 break; 288 } 289 290 m_vk.cmdEndRenderPass(*m_cmdBuffer); 291 m_vk.endCommandBuffer(*m_cmdBuffer); 292 293 vk::VkSubmitInfo submitInfo = 294 { 295 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 296 DE_NULL, // const void* pNext; 297 0, // deUint32 waitSemaphoreCount; 298 DE_NULL, // const VkSemaphore* pWaitSemaphores; 299 (const vk::VkPipelineStageFlags*)DE_NULL, 300 1, // deUint32 commandBufferCount; 301 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 302 0, // deUint32 signalSemaphoreCount; 303 DE_NULL // const VkSemaphore* pSignalSemaphores; 304 }; 305 VK_CHECK(m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL)); 306 307 VK_CHECK(m_vk.queueWaitIdle(queue)); 308 309 // Validation 310 VK_CHECK(m_vk.queueWaitIdle(queue)); 311 312 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT)); 313 referenceFrame.allocLevel(0); 314 315 const deInt32 frameWidth = referenceFrame.getWidth(); 316 const deInt32 frameHeight = referenceFrame.getHeight(); 317 318 tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 319 320 ReferenceImageInstancedCoordinates refInstancedCoords; 321 322 for (int y = 0; y < frameHeight; y++) 323 { 324 const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f; 325 326 for (int x = 0; x < frameWidth; x++) 327 { 328 const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f; 329 330 if ((yCoord >= refInstancedCoords.bottom && 331 yCoord <= refInstancedCoords.top && 332 xCoord >= refInstancedCoords.left && 333 xCoord <= refInstancedCoords.right)) 334 referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y); 335 } 336 } 337 338 const vk::VkOffset3D zeroOffset = { 0, 0, 0 }; 339 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), 340 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT); 341 342 qpTestResult res = QP_TEST_RESULT_PASS; 343 344 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result", 345 referenceFrame.getLevel(0), renderedFrame, 0.05f, 346 tcu::COMPARE_LOG_RESULT)) { 347 res = QP_TEST_RESULT_FAIL; 348 } 349 350 return tcu::TestStatus(res, qpGetTestResultName(res)); 351 352} 353 354} // anonymous 355 356DrawIndexedTests::DrawIndexedTests (tcu::TestContext &testCtx) 357 : TestCaseGroup (testCtx, "indexed_draw", "drawing indexed geometry") 358{ 359 /* Left blank on purpose */ 360} 361 362DrawIndexedTests::~DrawIndexedTests (void) {} 363 364void DrawIndexedTests::init (void) 365{ 366 { 367 DrawIndexed::TestSpec testSpec; 368 testSpec.shaders[glu::SHADERTYPE_VERTEX] = "vulkan/draw/VertexFetch.vert"; 369 testSpec.shaders[glu::SHADERTYPE_FRAGMENT] = "vulkan/draw/VertexFetch.frag"; 370 371 testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 372 addChild(new InstanceFactory<DrawIndexed>(m_testCtx, "draw_indexed_triangle_list", "Draws indexed triangle list", testSpec)); 373 testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 374 addChild(new InstanceFactory<DrawIndexed>(m_testCtx, "draw_indexed_triangle_strip", "Draws indexed triangle strip", testSpec)); 375 } 376 { 377 DrawInstancedIndexed::TestSpec testSpec; 378 testSpec.shaders[glu::SHADERTYPE_VERTEX] = "vulkan/draw/VertexFetchInstancedFirstInstance.vert"; 379 testSpec.shaders[glu::SHADERTYPE_FRAGMENT] = "vulkan/draw/VertexFetch.frag"; 380 381 testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 382 addChild(new InstanceFactory<DrawInstancedIndexed>(m_testCtx, "draw_instanced_indexed_triangle_list", "Draws indexed triangle list", testSpec)); 383 testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 384 addChild(new InstanceFactory<DrawInstancedIndexed>(m_testCtx, "draw_instanced_indexed_triangle_strip", "Draws indexed triangle strip", testSpec)); 385 } 386} 387 388} // DrawTests 389} // vkt 390