1 /* 2 * Copyright (c) 2015-2016 The Khronos Group Inc. 3 * Copyright (c) 2015-2016 Valve Corporation 4 * Copyright (c) 2015-2016 LunarG, Inc. 5 * Copyright (c) 2015-2016 Google, Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 * Author: Courtney Goeltzenleuchter <courtney (at) LunarG.com> 20 * Author: Tony Barbour <tony (at) LunarG.com> 21 */ 22 23 #include "vkrenderframework.h" 24 25 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 26 #define GET_DEVICE_PROC_ADDR(dev, entrypoint) \ 27 { \ 28 fp##entrypoint = (PFN_vk##entrypoint)vkGetDeviceProcAddr(dev, "vk" #entrypoint); \ 29 assert(fp##entrypoint != NULL); \ 30 } 31 32 // TODO : These functions are duplicated is vk_layer_utils.cpp, share code 33 // Return true if format contains depth and stencil information 34 bool vk_format_is_depth_and_stencil(VkFormat format) { 35 bool is_ds = false; 36 37 switch (format) { 38 case VK_FORMAT_D16_UNORM_S8_UINT: 39 case VK_FORMAT_D24_UNORM_S8_UINT: 40 case VK_FORMAT_D32_SFLOAT_S8_UINT: 41 is_ds = true; 42 break; 43 default: 44 break; 45 } 46 return is_ds; 47 } 48 49 // Return true if format is a stencil-only format 50 bool vk_format_is_stencil_only(VkFormat format) { return (format == VK_FORMAT_S8_UINT); } 51 52 // Return true if format is a depth-only format 53 bool vk_format_is_depth_only(VkFormat format) { 54 bool is_depth = false; 55 56 switch (format) { 57 case VK_FORMAT_D16_UNORM: 58 case VK_FORMAT_X8_D24_UNORM_PACK32: 59 case VK_FORMAT_D32_SFLOAT: 60 is_depth = true; 61 break; 62 default: 63 break; 64 } 65 66 return is_depth; 67 } 68 69 VkRenderFramework::VkRenderFramework() 70 : inst(VK_NULL_HANDLE), m_device(NULL), m_commandPool(VK_NULL_HANDLE), m_commandBuffer(NULL), m_renderPass(VK_NULL_HANDLE), 71 m_framebuffer(VK_NULL_HANDLE), m_width(256.0), // default window width 72 m_height(256.0), // default window height 73 m_render_target_fmt(VK_FORMAT_R8G8B8A8_UNORM), m_depth_stencil_fmt(VK_FORMAT_UNDEFINED), m_clear_via_load_op(true), 74 m_depth_clear_color(1.0), m_stencil_clear_color(0), m_depthStencil(NULL), m_CreateDebugReportCallback(VK_NULL_HANDLE), 75 m_DestroyDebugReportCallback(VK_NULL_HANDLE), m_globalMsgCallback(VK_NULL_HANDLE), m_devMsgCallback(VK_NULL_HANDLE) { 76 77 memset(&m_renderPassBeginInfo, 0, sizeof(m_renderPassBeginInfo)); 78 m_renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; 79 80 // clear the back buffer to dark grey 81 m_clear_color.float32[0] = 0.25f; 82 m_clear_color.float32[1] = 0.25f; 83 m_clear_color.float32[2] = 0.25f; 84 m_clear_color.float32[3] = 0.0f; 85 } 86 87 VkRenderFramework::~VkRenderFramework() {} 88 89 void VkRenderFramework::InitFramework() { 90 std::vector<const char *> instance_layer_names; 91 std::vector<const char *> instance_extension_names; 92 std::vector<const char *> device_extension_names; 93 instance_extension_names.push_back(VK_KHR_SURFACE_EXTENSION_NAME); 94 device_extension_names.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); 95 #ifdef _WIN32 96 instance_extension_names.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); 97 #endif 98 #ifdef VK_USE_PLATFORM_XCB_KHR 99 instance_extension_names.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); 100 #endif 101 InitFramework(instance_layer_names, instance_extension_names, device_extension_names); 102 } 103 104 void VkRenderFramework::InitFramework(std::vector<const char *> instance_layer_names, 105 std::vector<const char *> instance_extension_names, 106 std::vector<const char *> device_extension_names, PFN_vkDebugReportCallbackEXT dbgFunction, 107 void *userData) { 108 VkInstanceCreateInfo instInfo = {}; 109 std::vector<VkExtensionProperties> instance_extensions; 110 std::vector<VkExtensionProperties> device_extensions; 111 VkResult U_ASSERT_ONLY err; 112 113 /* TODO: Verify requested extensions are available */ 114 115 instInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; 116 instInfo.pNext = NULL; 117 instInfo.pApplicationInfo = &app_info; 118 instInfo.enabledLayerCount = instance_layer_names.size(); 119 instInfo.ppEnabledLayerNames = instance_layer_names.data(); 120 instInfo.enabledExtensionCount = instance_extension_names.size(); 121 instInfo.ppEnabledExtensionNames = instance_extension_names.data(); 122 err = vkCreateInstance(&instInfo, NULL, &this->inst); 123 ASSERT_VK_SUCCESS(err); 124 125 err = vkEnumeratePhysicalDevices(inst, &this->gpu_count, NULL); 126 ASSERT_LE(this->gpu_count, ARRAY_SIZE(objs)) << "Too many gpus"; 127 ASSERT_VK_SUCCESS(err); 128 err = vkEnumeratePhysicalDevices(inst, &this->gpu_count, objs); 129 ASSERT_VK_SUCCESS(err); 130 ASSERT_GE(this->gpu_count, (uint32_t)1) << "No GPU available"; 131 if (dbgFunction) { 132 m_CreateDebugReportCallback = 133 (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(this->inst, "vkCreateDebugReportCallbackEXT"); 134 ASSERT_NE(m_CreateDebugReportCallback, (PFN_vkCreateDebugReportCallbackEXT)NULL) 135 << "Did not get function pointer for CreateDebugReportCallback"; 136 if (m_CreateDebugReportCallback) { 137 VkDebugReportCallbackCreateInfoEXT dbgCreateInfo; 138 memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo)); 139 dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; 140 dbgCreateInfo.flags = 141 VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; 142 dbgCreateInfo.pfnCallback = dbgFunction; 143 dbgCreateInfo.pUserData = userData; 144 145 err = m_CreateDebugReportCallback(this->inst, &dbgCreateInfo, NULL, &m_globalMsgCallback); 146 ASSERT_VK_SUCCESS(err); 147 148 m_DestroyDebugReportCallback = 149 (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(this->inst, "vkDestroyDebugReportCallbackEXT"); 150 ASSERT_NE(m_DestroyDebugReportCallback, (PFN_vkDestroyDebugReportCallbackEXT)NULL) 151 << "Did not get function pointer for " 152 "DestroyDebugReportCallback"; 153 m_DebugReportMessage = (PFN_vkDebugReportMessageEXT)vkGetInstanceProcAddr(this->inst, "vkDebugReportMessageEXT"); 154 ASSERT_NE(m_DebugReportMessage, (PFN_vkDebugReportMessageEXT)NULL) 155 << "Did not get function pointer for DebugReportMessage"; 156 } 157 } 158 159 /* TODO: Verify requested physical device extensions are available */ 160 this->device_extension_names = device_extension_names; 161 } 162 163 void VkRenderFramework::ShutdownFramework() { 164 delete m_commandBuffer; 165 if (m_commandPool) 166 vkDestroyCommandPool(device(), m_commandPool, NULL); 167 if (m_framebuffer) 168 vkDestroyFramebuffer(device(), m_framebuffer, NULL); 169 if (m_renderPass) 170 vkDestroyRenderPass(device(), m_renderPass, NULL); 171 172 if (m_globalMsgCallback) 173 m_DestroyDebugReportCallback(this->inst, m_globalMsgCallback, NULL); 174 if (m_devMsgCallback) 175 m_DestroyDebugReportCallback(this->inst, m_devMsgCallback, NULL); 176 177 while (!m_renderTargets.empty()) { 178 vkDestroyImageView(device(), m_renderTargets.back()->targetView(m_render_target_fmt), NULL); 179 vkDestroyImage(device(), m_renderTargets.back()->image(), NULL); 180 vkFreeMemory(device(), m_renderTargets.back()->memory(), NULL); 181 m_renderTargets.pop_back(); 182 } 183 184 delete m_depthStencil; 185 186 // reset the driver 187 delete m_device; 188 if (this->inst) 189 vkDestroyInstance(this->inst, NULL); 190 } 191 192 void VkRenderFramework::InitState(VkPhysicalDeviceFeatures *features) { 193 VkResult U_ASSERT_ONLY err; 194 195 m_device = new VkDeviceObj(0, objs[0], device_extension_names, features); 196 m_device->get_device_queue(); 197 198 m_depthStencil = new VkDepthStencilObj(m_device); 199 200 m_render_target_fmt = VkTestFramework::GetFormat(inst, m_device); 201 202 m_lineWidth = 1.0f; 203 204 m_depthBiasConstantFactor = 0.0f; 205 m_depthBiasClamp = 0.0f; 206 m_depthBiasSlopeFactor = 0.0f; 207 208 m_blendConstants[0] = 1.0f; 209 m_blendConstants[1] = 1.0f; 210 m_blendConstants[2] = 1.0f; 211 m_blendConstants[3] = 1.0f; 212 213 m_minDepthBounds = 0.f; 214 m_maxDepthBounds = 1.f; 215 216 m_compareMask = 0xff; 217 m_writeMask = 0xff; 218 m_reference = 0; 219 220 VkCommandPoolCreateInfo cmd_pool_info; 221 cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, cmd_pool_info.pNext = NULL, 222 cmd_pool_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 223 cmd_pool_info.flags = 0, err = vkCreateCommandPool(device(), &cmd_pool_info, NULL, &m_commandPool); 224 assert(!err); 225 226 m_commandBuffer = new VkCommandBufferObj(m_device, m_commandPool); 227 } 228 229 void VkRenderFramework::InitViewport(float width, float height) { 230 VkViewport viewport; 231 VkRect2D scissor; 232 viewport.x = 0; 233 viewport.y = 0; 234 viewport.width = 1.f * width; 235 viewport.height = 1.f * height; 236 viewport.minDepth = 0.f; 237 viewport.maxDepth = 1.f; 238 m_viewports.push_back(viewport); 239 240 scissor.extent.width = (int32_t)width; 241 scissor.extent.height = (int32_t)height; 242 scissor.offset.x = 0; 243 scissor.offset.y = 0; 244 m_scissors.push_back(scissor); 245 246 m_width = width; 247 m_height = height; 248 } 249 250 void VkRenderFramework::InitViewport() { InitViewport(m_width, m_height); } 251 void VkRenderFramework::InitRenderTarget() { InitRenderTarget(1); } 252 253 void VkRenderFramework::InitRenderTarget(uint32_t targets) { InitRenderTarget(targets, NULL); } 254 255 void VkRenderFramework::InitRenderTarget(VkImageView *dsBinding) { InitRenderTarget(1, dsBinding); } 256 257 void VkRenderFramework::InitRenderTarget(uint32_t targets, VkImageView *dsBinding) { 258 std::vector<VkAttachmentDescription> attachments; 259 std::vector<VkAttachmentReference> color_references; 260 std::vector<VkImageView> bindings; 261 attachments.reserve(targets + 1); // +1 for dsBinding 262 color_references.reserve(targets); 263 bindings.reserve(targets + 1); // +1 for dsBinding 264 265 VkAttachmentDescription att = {}; 266 att.format = m_render_target_fmt; 267 att.samples = VK_SAMPLE_COUNT_1_BIT; 268 att.loadOp = (m_clear_via_load_op) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD; 269 att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 270 att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 271 att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; 272 att.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 273 att.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 274 275 VkAttachmentReference ref = {}; 276 ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 277 278 m_renderPassClearValues.clear(); 279 VkClearValue clear = {}; 280 clear.color = m_clear_color; 281 282 VkImageView bind = {}; 283 284 for (uint32_t i = 0; i < targets; i++) { 285 attachments.push_back(att); 286 287 ref.attachment = i; 288 color_references.push_back(ref); 289 290 m_renderPassClearValues.push_back(clear); 291 292 VkImageObj *img = new VkImageObj(m_device); 293 294 VkFormatProperties props; 295 296 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), m_render_target_fmt, &props); 297 298 if (props.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) { 299 img->init((uint32_t)m_width, (uint32_t)m_height, m_render_target_fmt, 300 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_LINEAR); 301 } else if (props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) { 302 img->init((uint32_t)m_width, (uint32_t)m_height, m_render_target_fmt, 303 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL); 304 } else { 305 FAIL() << "Neither Linear nor Optimal allowed for render target"; 306 } 307 308 m_renderTargets.push_back(img); 309 bind = img->targetView(m_render_target_fmt); 310 bindings.push_back(bind); 311 } 312 313 VkSubpassDescription subpass = {}; 314 subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; 315 subpass.flags = 0; 316 subpass.inputAttachmentCount = 0; 317 subpass.pInputAttachments = NULL; 318 subpass.colorAttachmentCount = targets; 319 subpass.pColorAttachments = color_references.data(); 320 subpass.pResolveAttachments = NULL; 321 322 VkAttachmentReference ds_reference; 323 if (dsBinding) { 324 att.format = m_depth_stencil_fmt; 325 att.loadOp = (m_clear_via_load_op) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD; 326 ; 327 att.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 328 att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; 329 att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; 330 att.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 331 att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 332 attachments.push_back(att); 333 334 clear.depthStencil.depth = m_depth_clear_color; 335 clear.depthStencil.stencil = m_stencil_clear_color; 336 m_renderPassClearValues.push_back(clear); 337 338 bindings.push_back(*dsBinding); 339 340 ds_reference.attachment = targets; 341 ds_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 342 subpass.pDepthStencilAttachment = &ds_reference; 343 } else { 344 subpass.pDepthStencilAttachment = NULL; 345 } 346 347 subpass.preserveAttachmentCount = 0; 348 subpass.pPreserveAttachments = NULL; 349 350 VkRenderPassCreateInfo rp_info = {}; 351 rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 352 rp_info.attachmentCount = attachments.size(); 353 rp_info.pAttachments = attachments.data(); 354 rp_info.subpassCount = 1; 355 rp_info.pSubpasses = &subpass; 356 357 vkCreateRenderPass(device(), &rp_info, NULL, &m_renderPass); 358 359 // Create Framebuffer and RenderPass with color attachments and any 360 // depth/stencil attachment 361 VkFramebufferCreateInfo fb_info = {}; 362 fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; 363 fb_info.pNext = NULL; 364 fb_info.renderPass = m_renderPass; 365 fb_info.attachmentCount = bindings.size(); 366 fb_info.pAttachments = bindings.data(); 367 fb_info.width = (uint32_t)m_width; 368 fb_info.height = (uint32_t)m_height; 369 fb_info.layers = 1; 370 371 vkCreateFramebuffer(device(), &fb_info, NULL, &m_framebuffer); 372 373 m_renderPassBeginInfo.renderPass = m_renderPass; 374 m_renderPassBeginInfo.framebuffer = m_framebuffer; 375 m_renderPassBeginInfo.renderArea.extent.width = (int32_t)m_width; 376 m_renderPassBeginInfo.renderArea.extent.height = (int32_t)m_height; 377 m_renderPassBeginInfo.clearValueCount = m_renderPassClearValues.size(); 378 m_renderPassBeginInfo.pClearValues = m_renderPassClearValues.data(); 379 } 380 381 VkDeviceObj::VkDeviceObj(uint32_t id, VkPhysicalDevice obj) : vk_testing::Device(obj), id(id) { 382 init(); 383 384 props = phy().properties(); 385 queue_props = phy().queue_properties(); 386 } 387 388 VkDeviceObj::VkDeviceObj(uint32_t id, VkPhysicalDevice obj, std::vector<const char *> &extension_names, 389 VkPhysicalDeviceFeatures *features) 390 : vk_testing::Device(obj), id(id) { 391 init(extension_names, features); 392 393 props = phy().properties(); 394 queue_props = phy().queue_properties(); 395 } 396 397 void VkDeviceObj::get_device_queue() { 398 ASSERT_NE(true, graphics_queues().empty()); 399 m_queue = graphics_queues()[0]->handle(); 400 } 401 402 VkDescriptorSetObj::VkDescriptorSetObj(VkDeviceObj *device) : m_device(device), m_nextSlot(0) {} 403 404 VkDescriptorSetObj::~VkDescriptorSetObj() { 405 if (m_set) { 406 delete m_set; 407 } 408 } 409 410 int VkDescriptorSetObj::AppendDummy() { 411 /* request a descriptor but do not update it */ 412 VkDescriptorSetLayoutBinding binding = {}; 413 binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; 414 binding.descriptorCount = 1; 415 binding.binding = m_layout_bindings.size(); 416 binding.stageFlags = VK_SHADER_STAGE_ALL; 417 binding.pImmutableSamplers = NULL; 418 419 m_layout_bindings.push_back(binding); 420 m_type_counts[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER] += binding.descriptorCount; 421 422 return m_nextSlot++; 423 } 424 425 int VkDescriptorSetObj::AppendBuffer(VkDescriptorType type, VkConstantBufferObj &constantBuffer) { 426 assert(type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || 427 type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC); 428 VkDescriptorSetLayoutBinding binding = {}; 429 binding.descriptorType = type; 430 binding.descriptorCount = 1; 431 binding.binding = m_layout_bindings.size(); 432 binding.stageFlags = VK_SHADER_STAGE_ALL; 433 binding.pImmutableSamplers = NULL; 434 435 m_layout_bindings.push_back(binding); 436 m_type_counts[type] += binding.descriptorCount; 437 438 m_writes.push_back(vk_testing::Device::write_descriptor_set(vk_testing::DescriptorSet(), m_nextSlot, 0, type, 1, 439 &constantBuffer.m_descriptorBufferInfo)); 440 441 return m_nextSlot++; 442 } 443 444 int VkDescriptorSetObj::AppendSamplerTexture(VkSamplerObj *sampler, VkTextureObj *texture) { 445 VkDescriptorSetLayoutBinding binding = {}; 446 binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 447 binding.descriptorCount = 1; 448 binding.binding = m_layout_bindings.size(); 449 binding.stageFlags = VK_SHADER_STAGE_ALL; 450 binding.pImmutableSamplers = NULL; 451 452 m_layout_bindings.push_back(binding); 453 m_type_counts[VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER] += binding.descriptorCount; 454 VkDescriptorImageInfo tmp = texture->m_imageInfo; 455 tmp.sampler = sampler->handle(); 456 m_imageSamplerDescriptors.push_back(tmp); 457 458 m_writes.push_back(vk_testing::Device::write_descriptor_set(vk_testing::DescriptorSet(), m_nextSlot, 0, 459 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, &tmp)); 460 461 return m_nextSlot++; 462 } 463 464 VkPipelineLayout VkDescriptorSetObj::GetPipelineLayout() const { return m_pipeline_layout.handle(); } 465 466 VkDescriptorSet VkDescriptorSetObj::GetDescriptorSetHandle() const { return m_set->handle(); } 467 468 void VkDescriptorSetObj::CreateVKDescriptorSet(VkCommandBufferObj *commandBuffer) { 469 470 if (m_type_counts.size()) { 471 // create VkDescriptorPool 472 VkDescriptorPoolSize poolSize; 473 vector<VkDescriptorPoolSize> sizes; 474 for (auto it = m_type_counts.begin(); it != m_type_counts.end(); ++it) { 475 poolSize.descriptorCount = it->second; 476 poolSize.type = it->first; 477 sizes.push_back(poolSize); 478 } 479 VkDescriptorPoolCreateInfo pool = {}; 480 pool.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 481 pool.poolSizeCount = sizes.size(); 482 pool.maxSets = 1; 483 pool.pPoolSizes = sizes.data(); 484 init(*m_device, pool); 485 } 486 487 // create VkDescriptorSetLayout 488 VkDescriptorSetLayoutCreateInfo layout = {}; 489 layout.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 490 layout.bindingCount = m_layout_bindings.size(); 491 layout.pBindings = m_layout_bindings.data(); 492 493 m_layout.init(*m_device, layout); 494 vector<const vk_testing::DescriptorSetLayout *> layouts; 495 layouts.push_back(&m_layout); 496 497 // create VkPipelineLayout 498 VkPipelineLayoutCreateInfo pipeline_layout = {}; 499 pipeline_layout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 500 pipeline_layout.setLayoutCount = layouts.size(); 501 pipeline_layout.pSetLayouts = NULL; 502 503 m_pipeline_layout.init(*m_device, pipeline_layout, layouts); 504 505 if (m_type_counts.size()) { 506 // create VkDescriptorSet 507 m_set = alloc_sets(*m_device, m_layout); 508 509 // build the update array 510 size_t imageSamplerCount = 0; 511 for (std::vector<VkWriteDescriptorSet>::iterator it = m_writes.begin(); it != m_writes.end(); it++) { 512 it->dstSet = m_set->handle(); 513 if (it->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) 514 it->pImageInfo = &m_imageSamplerDescriptors[imageSamplerCount++]; 515 } 516 517 // do the updates 518 m_device->update_descriptor_sets(m_writes); 519 } 520 } 521 522 VkRenderpassObj::VkRenderpassObj(VkDeviceObj *dev) { 523 // Create a renderPass with a single color attachment 524 VkAttachmentReference attach = {}; 525 attach.layout = VK_IMAGE_LAYOUT_GENERAL; 526 527 VkSubpassDescription subpass = {}; 528 subpass.pColorAttachments = &attach; 529 subpass.colorAttachmentCount = 1; 530 531 VkRenderPassCreateInfo rpci = {}; 532 rpci.subpassCount = 1; 533 rpci.pSubpasses = &subpass; 534 rpci.attachmentCount = 1; 535 536 VkAttachmentDescription attach_desc = {}; 537 attach_desc.format = VK_FORMAT_B8G8R8A8_UNORM; 538 attach_desc.samples = VK_SAMPLE_COUNT_1_BIT; 539 attach_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 540 attach_desc.finalLayout = VK_IMAGE_LAYOUT_GENERAL; 541 542 rpci.pAttachments = &attach_desc; 543 rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 544 545 device = dev->device(); 546 vkCreateRenderPass(device, &rpci, NULL, &m_renderpass); 547 } 548 549 VkRenderpassObj::~VkRenderpassObj() { vkDestroyRenderPass(device, m_renderpass, NULL); } 550 551 VkImageObj::VkImageObj(VkDeviceObj *dev) { 552 m_device = dev; 553 m_descriptorImageInfo.imageView = VK_NULL_HANDLE; 554 m_descriptorImageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL; 555 } 556 557 void VkImageObj::ImageMemoryBarrier(VkCommandBufferObj *cmd_buf, VkImageAspectFlags aspect, VkFlags output_mask /*= 558 VK_ACCESS_HOST_WRITE_BIT | 559 VK_ACCESS_SHADER_WRITE_BIT | 560 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 561 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | 562 VK_MEMORY_OUTPUT_COPY_BIT*/, 563 VkFlags input_mask /*= 564 VK_ACCESS_HOST_READ_BIT | 565 VK_ACCESS_INDIRECT_COMMAND_READ_BIT | 566 VK_ACCESS_INDEX_READ_BIT | 567 VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | 568 VK_ACCESS_UNIFORM_READ_BIT | 569 VK_ACCESS_SHADER_READ_BIT | 570 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 571 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | 572 VK_MEMORY_INPUT_COPY_BIT*/, VkImageLayout image_layout) { 573 const VkImageSubresourceRange subresourceRange = subresource_range(aspect, 0, 1, 0, 1); 574 VkImageMemoryBarrier barrier; 575 barrier = image_memory_barrier(output_mask, input_mask, layout(), image_layout, subresourceRange); 576 577 VkImageMemoryBarrier *pmemory_barrier = &barrier; 578 579 VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 580 VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 581 582 // write barrier to the command buffer 583 vkCmdPipelineBarrier(cmd_buf->handle(), src_stages, dest_stages, 0, 0, NULL, 0, NULL, 1, pmemory_barrier); 584 } 585 586 void VkImageObj::SetLayout(VkCommandBufferObj *cmd_buf, VkImageAspectFlags aspect, VkImageLayout image_layout) { 587 VkFlags src_mask, dst_mask; 588 const VkFlags all_cache_outputs = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 589 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; 590 const VkFlags all_cache_inputs = VK_ACCESS_HOST_READ_BIT | VK_ACCESS_INDIRECT_COMMAND_READ_BIT | VK_ACCESS_INDEX_READ_BIT | 591 VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_UNIFORM_READ_BIT | VK_ACCESS_SHADER_READ_BIT | 592 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | 593 VK_ACCESS_MEMORY_READ_BIT; 594 595 if (image_layout == m_descriptorImageInfo.imageLayout) { 596 return; 597 } 598 599 switch (image_layout) { 600 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: 601 if (m_descriptorImageInfo.imageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) 602 src_mask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 603 else 604 src_mask = VK_ACCESS_TRANSFER_WRITE_BIT; 605 dst_mask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT; 606 break; 607 608 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: 609 if (m_descriptorImageInfo.imageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) 610 src_mask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 611 else if (m_descriptorImageInfo.imageLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) 612 src_mask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; 613 else 614 src_mask = VK_ACCESS_TRANSFER_WRITE_BIT; 615 dst_mask = VK_ACCESS_TRANSFER_WRITE_BIT; 616 break; 617 618 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: 619 if (m_descriptorImageInfo.imageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) 620 src_mask = VK_ACCESS_TRANSFER_WRITE_BIT; 621 else 622 src_mask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; 623 dst_mask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_MEMORY_READ_BIT; 624 break; 625 626 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: 627 if (m_descriptorImageInfo.imageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) 628 src_mask = VK_ACCESS_TRANSFER_READ_BIT; 629 else 630 src_mask = 0; 631 dst_mask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 632 break; 633 634 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: 635 dst_mask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 636 src_mask = all_cache_outputs; 637 break; 638 639 default: 640 src_mask = all_cache_outputs; 641 dst_mask = all_cache_inputs; 642 break; 643 } 644 645 if (m_descriptorImageInfo.imageLayout == VK_IMAGE_LAYOUT_UNDEFINED) 646 src_mask = 0; 647 648 ImageMemoryBarrier(cmd_buf, aspect, src_mask, dst_mask, image_layout); 649 m_descriptorImageInfo.imageLayout = image_layout; 650 } 651 652 void VkImageObj::SetLayout(VkImageAspectFlags aspect, VkImageLayout image_layout) { 653 VkResult U_ASSERT_ONLY err; 654 655 if (image_layout == m_descriptorImageInfo.imageLayout) { 656 return; 657 } 658 659 VkCommandPoolCreateInfo cmd_pool_info = {}; 660 cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 661 cmd_pool_info.pNext = NULL; 662 cmd_pool_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 663 cmd_pool_info.flags = 0; 664 vk_testing::CommandPool pool(*m_device, cmd_pool_info); 665 VkCommandBufferObj cmd_buf(m_device, pool.handle()); 666 667 /* Build command buffer to set image layout in the driver */ 668 err = cmd_buf.BeginCommandBuffer(); 669 assert(!err); 670 671 SetLayout(&cmd_buf, aspect, image_layout); 672 673 err = cmd_buf.EndCommandBuffer(); 674 assert(!err); 675 676 cmd_buf.QueueCommandBuffer(); 677 } 678 679 bool VkImageObj::IsCompatible(VkFlags usage, VkFlags features) { 680 if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) && !(features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) 681 return false; 682 683 return true; 684 } 685 686 void VkImageObj::init_no_layout(uint32_t w, uint32_t h, VkFormat fmt, VkFlags usage, VkImageTiling requested_tiling, 687 VkMemoryPropertyFlags reqs) { 688 689 VkFormatProperties image_fmt; 690 VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL; 691 692 vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), fmt, &image_fmt); 693 694 if (requested_tiling == VK_IMAGE_TILING_LINEAR) { 695 if (IsCompatible(usage, image_fmt.linearTilingFeatures)) { 696 tiling = VK_IMAGE_TILING_LINEAR; 697 } else if (IsCompatible(usage, image_fmt.optimalTilingFeatures)) { 698 tiling = VK_IMAGE_TILING_OPTIMAL; 699 } else { 700 ASSERT_TRUE(false) << "Error: Cannot find requested tiling configuration"; 701 } 702 } else if (IsCompatible(usage, image_fmt.optimalTilingFeatures)) { 703 tiling = VK_IMAGE_TILING_OPTIMAL; 704 } else if (IsCompatible(usage, image_fmt.linearTilingFeatures)) { 705 tiling = VK_IMAGE_TILING_LINEAR; 706 } else { 707 ASSERT_TRUE(false) << "Error: Cannot find requested tiling configuration"; 708 } 709 710 VkImageCreateInfo imageCreateInfo = vk_testing::Image::create_info(); 711 imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; 712 imageCreateInfo.format = fmt; 713 imageCreateInfo.extent.width = w; 714 imageCreateInfo.extent.height = h; 715 imageCreateInfo.mipLevels = 1; 716 imageCreateInfo.tiling = tiling; 717 imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 718 719 layout(imageCreateInfo.initialLayout); 720 imageCreateInfo.usage = usage; 721 722 vk_testing::Image::init(*m_device, imageCreateInfo, reqs); 723 } 724 725 void VkImageObj::init(uint32_t w, uint32_t h, VkFormat fmt, VkFlags usage, VkImageTiling requested_tiling, 726 VkMemoryPropertyFlags reqs) { 727 728 init_no_layout(w, h, fmt, usage, requested_tiling, reqs); 729 730 VkImageLayout newLayout; 731 if (usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) 732 newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 733 else if (usage & VK_IMAGE_USAGE_SAMPLED_BIT) 734 newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 735 else 736 newLayout = m_descriptorImageInfo.imageLayout; 737 738 VkImageAspectFlags image_aspect = 0; 739 if (vk_format_is_depth_and_stencil(fmt)) { 740 image_aspect = VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT; 741 } else if (vk_format_is_depth_only(fmt)) { 742 image_aspect = VK_IMAGE_ASPECT_DEPTH_BIT; 743 } else if (vk_format_is_stencil_only(fmt)) { 744 image_aspect = VK_IMAGE_ASPECT_STENCIL_BIT; 745 } else { // color 746 image_aspect = VK_IMAGE_ASPECT_COLOR_BIT; 747 } 748 SetLayout(image_aspect, newLayout); 749 } 750 751 VkResult VkImageObj::CopyImage(VkImageObj &src_image) { 752 VkResult U_ASSERT_ONLY err; 753 VkImageLayout src_image_layout, dest_image_layout; 754 755 VkCommandPoolCreateInfo cmd_pool_info = {}; 756 cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 757 cmd_pool_info.pNext = NULL; 758 cmd_pool_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 759 cmd_pool_info.flags = 0; 760 vk_testing::CommandPool pool(*m_device, cmd_pool_info); 761 VkCommandBufferObj cmd_buf(m_device, pool.handle()); 762 763 /* Build command buffer to copy staging texture to usable texture */ 764 err = cmd_buf.BeginCommandBuffer(); 765 assert(!err); 766 767 /* TODO: Can we determine image aspect from image object? */ 768 src_image_layout = src_image.layout(); 769 src_image.SetLayout(&cmd_buf, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); 770 771 dest_image_layout = (this->layout() == VK_IMAGE_LAYOUT_UNDEFINED) ? VK_IMAGE_LAYOUT_GENERAL : this->layout(); 772 this->SetLayout(&cmd_buf, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); 773 774 VkImageCopy copy_region = {}; 775 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 776 copy_region.srcSubresource.baseArrayLayer = 0; 777 copy_region.srcSubresource.mipLevel = 0; 778 copy_region.srcSubresource.layerCount = 1; 779 copy_region.srcOffset.x = 0; 780 copy_region.srcOffset.y = 0; 781 copy_region.srcOffset.z = 0; 782 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 783 copy_region.dstSubresource.baseArrayLayer = 0; 784 copy_region.dstSubresource.mipLevel = 0; 785 copy_region.dstSubresource.layerCount = 1; 786 copy_region.dstOffset.x = 0; 787 copy_region.dstOffset.y = 0; 788 copy_region.dstOffset.z = 0; 789 copy_region.extent = src_image.extent(); 790 791 vkCmdCopyImage(cmd_buf.handle(), src_image.handle(), src_image.layout(), handle(), layout(), 1, ©_region); 792 793 src_image.SetLayout(&cmd_buf, VK_IMAGE_ASPECT_COLOR_BIT, src_image_layout); 794 795 this->SetLayout(&cmd_buf, VK_IMAGE_ASPECT_COLOR_BIT, dest_image_layout); 796 797 err = cmd_buf.EndCommandBuffer(); 798 assert(!err); 799 800 cmd_buf.QueueCommandBuffer(); 801 802 return VK_SUCCESS; 803 } 804 805 VkTextureObj::VkTextureObj(VkDeviceObj *device, uint32_t *colors) : VkImageObj(device) { 806 m_device = device; 807 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM; 808 uint32_t tex_colors[2] = {0xffff0000, 0xff00ff00}; 809 void *data; 810 uint32_t x, y; 811 VkImageObj stagingImage(device); 812 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; 813 814 stagingImage.init(16, 16, tex_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_LINEAR, 815 reqs); 816 VkSubresourceLayout layout = stagingImage.subresource_layout(subresource(VK_IMAGE_ASPECT_COLOR_BIT, 0, 0)); 817 818 if (colors == NULL) 819 colors = tex_colors; 820 821 memset(&m_imageInfo, 0, sizeof(m_imageInfo)); 822 823 VkImageViewCreateInfo view = {}; 824 view.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 825 view.pNext = NULL; 826 view.image = VK_NULL_HANDLE; 827 view.viewType = VK_IMAGE_VIEW_TYPE_2D; 828 view.format = tex_format; 829 view.components.r = VK_COMPONENT_SWIZZLE_R; 830 view.components.g = VK_COMPONENT_SWIZZLE_G; 831 view.components.b = VK_COMPONENT_SWIZZLE_B; 832 view.components.a = VK_COMPONENT_SWIZZLE_A; 833 view.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 834 view.subresourceRange.baseMipLevel = 0; 835 view.subresourceRange.levelCount = 1; 836 view.subresourceRange.baseArrayLayer = 0; 837 view.subresourceRange.layerCount = 1; 838 839 /* create image */ 840 init(16, 16, tex_format, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL); 841 stagingImage.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL); 842 843 /* create image view */ 844 view.image = handle(); 845 m_textureView.init(*m_device, view); 846 m_imageInfo.imageView = m_textureView.handle(); 847 848 data = stagingImage.MapMemory(); 849 850 for (y = 0; y < extent().height; y++) { 851 uint32_t *row = (uint32_t *)((char *)data + layout.rowPitch * y); 852 for (x = 0; x < extent().width; x++) 853 row[x] = colors[(x & 1) ^ (y & 1)]; 854 } 855 stagingImage.UnmapMemory(); 856 stagingImage.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); 857 VkImageObj::CopyImage(stagingImage); 858 } 859 860 VkSamplerObj::VkSamplerObj(VkDeviceObj *device) { 861 m_device = device; 862 863 VkSamplerCreateInfo samplerCreateInfo; 864 memset(&samplerCreateInfo, 0, sizeof(samplerCreateInfo)); 865 samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; 866 samplerCreateInfo.magFilter = VK_FILTER_NEAREST; 867 samplerCreateInfo.minFilter = VK_FILTER_NEAREST; 868 samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; 869 samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; 870 samplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; 871 samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; 872 samplerCreateInfo.mipLodBias = 0.0; 873 samplerCreateInfo.anisotropyEnable = VK_FALSE; 874 samplerCreateInfo.maxAnisotropy = 1; 875 samplerCreateInfo.compareOp = VK_COMPARE_OP_NEVER; 876 samplerCreateInfo.minLod = 0.0; 877 samplerCreateInfo.maxLod = 0.0; 878 samplerCreateInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; 879 samplerCreateInfo.unnormalizedCoordinates = VK_FALSE; 880 881 init(*m_device, samplerCreateInfo); 882 } 883 884 /* 885 * Basic ConstantBuffer constructor. Then use create methods to fill in the 886 * details. 887 */ 888 VkConstantBufferObj::VkConstantBufferObj(VkDeviceObj *device, VkBufferUsageFlags usage) { 889 m_device = device; 890 m_commandBuffer = 0; 891 892 memset(&m_descriptorBufferInfo, 0, sizeof(m_descriptorBufferInfo)); 893 894 // Special case for usages outside of original limits of framework 895 if ((VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT) != usage) { 896 init_no_mem(*m_device, create_info(0, usage)); 897 } 898 } 899 900 VkConstantBufferObj::~VkConstantBufferObj() { 901 // TODO: Should we call QueueRemoveMemReference for the constant buffer 902 // memory here? 903 if (m_commandBuffer) { 904 delete m_commandBuffer; 905 delete m_commandPool; 906 } 907 } 908 909 VkConstantBufferObj::VkConstantBufferObj(VkDeviceObj *device, int constantCount, int constantSize, const void *data, 910 VkBufferUsageFlags usage) { 911 m_device = device; 912 m_commandBuffer = 0; 913 914 memset(&m_descriptorBufferInfo, 0, sizeof(m_descriptorBufferInfo)); 915 m_numVertices = constantCount; 916 m_stride = constantSize; 917 918 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; 919 const VkDeviceSize allocationSize = static_cast<VkDeviceSize>(constantCount * constantSize); 920 921 if ((VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT) == usage) { 922 init_as_src_and_dst(*m_device, allocationSize, reqs); 923 } else { 924 init(*m_device, create_info(allocationSize, usage), reqs); 925 } 926 927 void *pData = memory().map(); 928 memcpy(pData, data, static_cast<size_t>(allocationSize)); 929 memory().unmap(); 930 931 /* 932 * Constant buffers are going to be used as vertex input buffers 933 * or as shader uniform buffers. So, we'll create the shaderbuffer 934 * descriptor here so it's ready if needed. 935 */ 936 this->m_descriptorBufferInfo.buffer = handle(); 937 this->m_descriptorBufferInfo.offset = 0; 938 this->m_descriptorBufferInfo.range = allocationSize; 939 } 940 941 void VkConstantBufferObj::Bind(VkCommandBuffer commandBuffer, VkDeviceSize offset, uint32_t binding) { 942 vkCmdBindVertexBuffers(commandBuffer, binding, 1, &handle(), &offset); 943 } 944 945 void VkConstantBufferObj::BufferMemoryBarrier(VkFlags srcAccessMask /*= 946 VK_ACCESS_HOST_WRITE_BIT | 947 VK_ACCESS_SHADER_WRITE_BIT | 948 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 949 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | 950 VK_MEMORY_OUTPUT_COPY_BIT*/, VkFlags dstAccessMask /*= 951 VK_ACCESS_HOST_READ_BIT | 952 VK_ACCESS_INDIRECT_COMMAND_READ_BIT | 953 VK_ACCESS_INDEX_READ_BIT | 954 VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | 955 VK_ACCESS_UNIFORM_READ_BIT | 956 VK_ACCESS_SHADER_READ_BIT | 957 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 958 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | 959 VK_MEMORY_INPUT_COPY_BIT*/) { 960 VkResult err = VK_SUCCESS; 961 962 if (!m_commandBuffer) { 963 m_fence.init(*m_device, vk_testing::Fence::create_info()); 964 VkCommandPoolCreateInfo cmd_pool_info = {}; 965 cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 966 cmd_pool_info.pNext = NULL; 967 cmd_pool_info.queueFamilyIndex = m_device->graphics_queue_node_index_; 968 cmd_pool_info.flags = 0; 969 m_commandPool = new vk_testing::CommandPool(*m_device, cmd_pool_info); 970 m_commandBuffer = new VkCommandBufferObj(m_device, m_commandPool->handle()); 971 } else { 972 m_device->wait(m_fence); 973 } 974 975 // open the command buffer 976 VkCommandBufferBeginInfo cmd_buf_info = {}; 977 VkCommandBufferInheritanceInfo cmd_buf_hinfo = {}; 978 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 979 cmd_buf_info.pNext = NULL; 980 cmd_buf_info.flags = 0; 981 cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo; 982 983 cmd_buf_hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; 984 cmd_buf_hinfo.pNext = NULL; 985 cmd_buf_hinfo.renderPass = VK_NULL_HANDLE; 986 cmd_buf_hinfo.subpass = 0; 987 cmd_buf_hinfo.framebuffer = VK_NULL_HANDLE; 988 cmd_buf_hinfo.occlusionQueryEnable = VK_FALSE; 989 cmd_buf_hinfo.queryFlags = 0; 990 cmd_buf_hinfo.pipelineStatistics = 0; 991 992 err = m_commandBuffer->BeginCommandBuffer(&cmd_buf_info); 993 ASSERT_VK_SUCCESS(err); 994 995 VkBufferMemoryBarrier memory_barrier = buffer_memory_barrier(srcAccessMask, dstAccessMask, 0, m_numVertices * m_stride); 996 VkBufferMemoryBarrier *pmemory_barrier = &memory_barrier; 997 998 VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 999 VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 1000 1001 // write barrier to the command buffer 1002 m_commandBuffer->PipelineBarrier(src_stages, dest_stages, 0, 0, NULL, 1, pmemory_barrier, 0, NULL); 1003 1004 // finish recording the command buffer 1005 err = m_commandBuffer->EndCommandBuffer(); 1006 ASSERT_VK_SUCCESS(err); 1007 1008 // submit the command buffer to the universal queue 1009 VkCommandBuffer bufferArray[1]; 1010 bufferArray[0] = m_commandBuffer->GetBufferHandle(); 1011 VkSubmitInfo submit_info; 1012 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 1013 submit_info.pNext = NULL; 1014 submit_info.waitSemaphoreCount = 0; 1015 submit_info.pWaitSemaphores = NULL; 1016 submit_info.pWaitDstStageMask = NULL; 1017 submit_info.commandBufferCount = 1; 1018 submit_info.pCommandBuffers = bufferArray; 1019 submit_info.signalSemaphoreCount = 0; 1020 submit_info.pSignalSemaphores = NULL; 1021 1022 err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, m_fence.handle()); 1023 ASSERT_VK_SUCCESS(err); 1024 } 1025 1026 VkIndexBufferObj::VkIndexBufferObj(VkDeviceObj *device) : VkConstantBufferObj(device) {} 1027 1028 void VkIndexBufferObj::CreateAndInitBuffer(int numIndexes, VkIndexType indexType, const void *data) { 1029 m_numVertices = numIndexes; 1030 m_indexType = indexType; 1031 switch (indexType) { 1032 case VK_INDEX_TYPE_UINT16: 1033 m_stride = 2; 1034 break; 1035 case VK_INDEX_TYPE_UINT32: 1036 m_stride = 4; 1037 break; 1038 default: 1039 assert(!"unknown index type"); 1040 m_stride = 2; 1041 break; 1042 } 1043 1044 const size_t allocationSize = numIndexes * m_stride; 1045 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; 1046 init_as_src_and_dst(*m_device, allocationSize, reqs); 1047 1048 void *pData = memory().map(); 1049 memcpy(pData, data, allocationSize); 1050 memory().unmap(); 1051 1052 // set up the descriptor for the constant buffer 1053 this->m_descriptorBufferInfo.buffer = handle(); 1054 this->m_descriptorBufferInfo.offset = 0; 1055 this->m_descriptorBufferInfo.range = allocationSize; 1056 } 1057 1058 void VkIndexBufferObj::Bind(VkCommandBuffer commandBuffer, VkDeviceSize offset) { 1059 vkCmdBindIndexBuffer(commandBuffer, handle(), offset, m_indexType); 1060 } 1061 1062 VkIndexType VkIndexBufferObj::GetIndexType() { return m_indexType; } 1063 1064 VkPipelineShaderStageCreateInfo VkShaderObj::GetStageCreateInfo() const { 1065 VkPipelineShaderStageCreateInfo stageInfo = {}; 1066 1067 stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 1068 stageInfo.stage = m_stage; 1069 stageInfo.module = handle(); 1070 stageInfo.pName = m_name; 1071 1072 return stageInfo; 1073 } 1074 1075 VkShaderObj::VkShaderObj(VkDeviceObj *device, const char *shader_code, VkShaderStageFlagBits stage, VkRenderFramework *framework, 1076 char const *name) { 1077 VkResult U_ASSERT_ONLY err = VK_SUCCESS; 1078 std::vector<unsigned int> spv; 1079 VkShaderModuleCreateInfo moduleCreateInfo; 1080 size_t shader_len; 1081 1082 m_stage = stage; 1083 m_device = device; 1084 m_name = name; 1085 1086 moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; 1087 moduleCreateInfo.pNext = NULL; 1088 1089 if (framework->m_use_glsl) { 1090 1091 shader_len = strlen(shader_code); 1092 moduleCreateInfo.codeSize = 3 * sizeof(uint32_t) + shader_len + 1; 1093 moduleCreateInfo.pCode = (uint32_t *)malloc(moduleCreateInfo.codeSize); 1094 moduleCreateInfo.flags = 0; 1095 1096 /* try version 0 first: VkShaderStage followed by GLSL */ 1097 ((uint32_t *)moduleCreateInfo.pCode)[0] = ICD_SPV_MAGIC; 1098 ((uint32_t *)moduleCreateInfo.pCode)[1] = 0; 1099 ((uint32_t *)moduleCreateInfo.pCode)[2] = stage; 1100 memcpy(((uint32_t *)moduleCreateInfo.pCode + 3), shader_code, shader_len + 1); 1101 1102 } else { 1103 1104 // Use Reference GLSL to SPV compiler 1105 framework->GLSLtoSPV(stage, shader_code, spv); 1106 moduleCreateInfo.pCode = spv.data(); 1107 moduleCreateInfo.codeSize = spv.size() * sizeof(unsigned int); 1108 moduleCreateInfo.flags = 0; 1109 } 1110 1111 err = init_try(*m_device, moduleCreateInfo); 1112 assert(VK_SUCCESS == err); 1113 } 1114 1115 VkPipelineObj::VkPipelineObj(VkDeviceObj *device) { 1116 m_device = device; 1117 1118 m_vi_state.pNext = VK_NULL_HANDLE; 1119 m_vi_state.flags = 0; 1120 m_vi_state.vertexBindingDescriptionCount = 0; 1121 m_vi_state.pVertexBindingDescriptions = VK_NULL_HANDLE; 1122 m_vi_state.vertexAttributeDescriptionCount = 0; 1123 m_vi_state.pVertexAttributeDescriptions = VK_NULL_HANDLE; 1124 1125 m_vertexBufferCount = 0; 1126 1127 m_ia_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 1128 m_ia_state.pNext = VK_NULL_HANDLE; 1129 m_ia_state.flags = 0; 1130 m_ia_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 1131 m_ia_state.primitiveRestartEnable = VK_FALSE; 1132 1133 m_rs_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 1134 m_rs_state.pNext = VK_NULL_HANDLE; 1135 m_rs_state.flags = 0; 1136 m_rs_state.depthClampEnable = VK_TRUE; 1137 m_rs_state.rasterizerDiscardEnable = VK_FALSE; 1138 m_rs_state.polygonMode = VK_POLYGON_MODE_FILL; 1139 m_rs_state.cullMode = VK_CULL_MODE_BACK_BIT; 1140 m_rs_state.frontFace = VK_FRONT_FACE_CLOCKWISE; 1141 m_rs_state.depthBiasEnable = VK_FALSE; 1142 m_rs_state.lineWidth = 1.0f; 1143 m_rs_state.depthBiasConstantFactor = 0.0f; 1144 m_rs_state.depthBiasClamp = 0.0f; 1145 m_rs_state.depthBiasSlopeFactor = 0.0f; 1146 1147 memset(&m_cb_state, 0, sizeof(m_cb_state)); 1148 m_cb_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 1149 m_cb_state.pNext = VK_NULL_HANDLE; 1150 m_cb_state.logicOp = VK_LOGIC_OP_COPY; 1151 m_cb_state.blendConstants[0] = 1.0f; 1152 m_cb_state.blendConstants[1] = 1.0f; 1153 m_cb_state.blendConstants[2] = 1.0f; 1154 m_cb_state.blendConstants[3] = 1.0f; 1155 1156 m_ms_state.pNext = VK_NULL_HANDLE; 1157 m_ms_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 1158 m_ms_state.flags = 0; 1159 m_ms_state.pSampleMask = NULL; 1160 m_ms_state.alphaToCoverageEnable = VK_FALSE; 1161 m_ms_state.alphaToOneEnable = VK_FALSE; 1162 m_ms_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 1163 m_ms_state.minSampleShading = 0; 1164 m_ms_state.sampleShadingEnable = 0; 1165 1166 m_vp_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 1167 m_vp_state.pNext = VK_NULL_HANDLE; 1168 m_vp_state.flags = 0; 1169 m_vp_state.viewportCount = 1; 1170 m_vp_state.scissorCount = 1; 1171 m_vp_state.pViewports = NULL; 1172 m_vp_state.pScissors = NULL; 1173 1174 m_ds_state = nullptr; 1175 }; 1176 1177 void VkPipelineObj::AddShader(VkShaderObj *shader) { m_shaderObjs.push_back(shader); } 1178 1179 void VkPipelineObj::AddVertexInputAttribs(VkVertexInputAttributeDescription *vi_attrib, uint32_t count) { 1180 m_vi_state.pVertexAttributeDescriptions = vi_attrib; 1181 m_vi_state.vertexAttributeDescriptionCount = count; 1182 } 1183 1184 void VkPipelineObj::AddVertexInputBindings(VkVertexInputBindingDescription *vi_binding, uint32_t count) { 1185 m_vi_state.pVertexBindingDescriptions = vi_binding; 1186 m_vi_state.vertexBindingDescriptionCount = count; 1187 } 1188 1189 void VkPipelineObj::AddColorAttachment(uint32_t binding, const VkPipelineColorBlendAttachmentState *att) { 1190 if (binding + 1 > m_colorAttachments.size()) { 1191 m_colorAttachments.resize(binding + 1); 1192 } 1193 m_colorAttachments[binding] = *att; 1194 } 1195 1196 void VkPipelineObj::SetDepthStencil(const VkPipelineDepthStencilStateCreateInfo *ds_state) { 1197 m_ds_state = ds_state; 1198 } 1199 1200 void VkPipelineObj::SetViewport(const vector<VkViewport> viewports) { 1201 m_viewports = viewports; 1202 // If we explicitly set a null viewport, pass it through to create info 1203 // but preserve viewportCount because it musn't change 1204 if (m_viewports.size() == 0) { 1205 m_vp_state.pViewports = nullptr; 1206 } 1207 } 1208 1209 void VkPipelineObj::SetScissor(const vector<VkRect2D> scissors) { 1210 m_scissors = scissors; 1211 // If we explicitly set a null scissors, pass it through to create info 1212 // but preserve viewportCount because it musn't change 1213 if (m_scissors.size() == 0) { 1214 m_vp_state.pScissors = nullptr; 1215 } 1216 } 1217 1218 void VkPipelineObj::MakeDynamic(VkDynamicState state) { 1219 /* Only add a state once */ 1220 for (auto it = m_dynamic_state_enables.begin(); it != m_dynamic_state_enables.end(); it++) { 1221 if ((*it) == state) 1222 return; 1223 } 1224 m_dynamic_state_enables.push_back(state); 1225 } 1226 1227 void VkPipelineObj::SetMSAA(const VkPipelineMultisampleStateCreateInfo *ms_state) { m_ms_state = *ms_state; } 1228 1229 void VkPipelineObj::SetInputAssembly(const VkPipelineInputAssemblyStateCreateInfo *ia_state) { m_ia_state = *ia_state; } 1230 1231 void VkPipelineObj::SetRasterization(const VkPipelineRasterizationStateCreateInfo *rs_state) { m_rs_state = *rs_state; } 1232 1233 void VkPipelineObj::SetTessellation(const VkPipelineTessellationStateCreateInfo *te_state) { m_te_state = *te_state; } 1234 1235 VkResult VkPipelineObj::CreateVKPipeline(VkPipelineLayout layout, VkRenderPass render_pass) { 1236 VkGraphicsPipelineCreateInfo info = {}; 1237 VkPipelineDynamicStateCreateInfo dsci = {}; 1238 1239 info.stageCount = m_shaderObjs.size(); 1240 info.pStages = new VkPipelineShaderStageCreateInfo[info.stageCount]; 1241 1242 for (size_t i = 0; i < m_shaderObjs.size(); i++) { 1243 ((VkPipelineShaderStageCreateInfo *)info.pStages)[i] = m_shaderObjs[i]->GetStageCreateInfo(); 1244 } 1245 1246 m_vi_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 1247 info.pVertexInputState = &m_vi_state; 1248 1249 m_ia_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 1250 info.pInputAssemblyState = &m_ia_state; 1251 1252 info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 1253 info.pNext = NULL; 1254 info.flags = 0; 1255 info.layout = layout; 1256 1257 m_cb_state.attachmentCount = m_colorAttachments.size(); 1258 m_cb_state.pAttachments = m_colorAttachments.data(); 1259 1260 if (m_viewports.size() > 0) { 1261 m_vp_state.viewportCount = m_viewports.size(); 1262 m_vp_state.pViewports = m_viewports.data(); 1263 } else { 1264 MakeDynamic(VK_DYNAMIC_STATE_VIEWPORT); 1265 } 1266 1267 if (m_scissors.size() > 0) { 1268 m_vp_state.scissorCount = m_scissors.size(); 1269 m_vp_state.pScissors = m_scissors.data(); 1270 } else { 1271 MakeDynamic(VK_DYNAMIC_STATE_SCISSOR); 1272 } 1273 1274 if (m_dynamic_state_enables.size() > 0) { 1275 dsci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 1276 dsci.dynamicStateCount = m_dynamic_state_enables.size(); 1277 dsci.pDynamicStates = m_dynamic_state_enables.data(); 1278 info.pDynamicState = &dsci; 1279 } 1280 1281 info.renderPass = render_pass; 1282 info.subpass = 0; 1283 info.pViewportState = &m_vp_state; 1284 info.pRasterizationState = &m_rs_state; 1285 info.pMultisampleState = &m_ms_state; 1286 info.pDepthStencilState = m_ds_state; 1287 info.pColorBlendState = &m_cb_state; 1288 1289 if (m_ia_state.topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) { 1290 m_te_state.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; 1291 info.pTessellationState = &m_te_state; 1292 } else { 1293 info.pTessellationState = nullptr; 1294 } 1295 1296 return init_try(*m_device, info); 1297 } 1298 1299 VkCommandBufferObj::VkCommandBufferObj(VkDeviceObj *device, VkCommandPool pool) { 1300 m_device = device; 1301 1302 init(*device, vk_testing::CommandBuffer::create_info(pool)); 1303 } 1304 1305 VkCommandBuffer VkCommandBufferObj::GetBufferHandle() { return handle(); } 1306 1307 VkResult VkCommandBufferObj::BeginCommandBuffer(VkCommandBufferBeginInfo *pInfo) { 1308 begin(pInfo); 1309 return VK_SUCCESS; 1310 } 1311 1312 VkResult VkCommandBufferObj::BeginCommandBuffer() { 1313 begin(); 1314 return VK_SUCCESS; 1315 } 1316 1317 VkResult VkCommandBufferObj::EndCommandBuffer() { 1318 end(); 1319 return VK_SUCCESS; 1320 } 1321 1322 void VkCommandBufferObj::PipelineBarrier(VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages, 1323 VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, 1324 const VkMemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount, 1325 const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, 1326 const VkImageMemoryBarrier *pImageMemoryBarriers) { 1327 vkCmdPipelineBarrier(handle(), src_stages, dest_stages, dependencyFlags, memoryBarrierCount, pMemoryBarriers, 1328 bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); 1329 } 1330 1331 void VkCommandBufferObj::ClearAllBuffers(VkClearColorValue clear_color, float depth_clear_color, uint32_t stencil_clear_color, 1332 VkDepthStencilObj *depthStencilObj) { 1333 uint32_t i; 1334 const VkFlags output_mask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 1335 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; 1336 const VkFlags input_mask = 0; 1337 1338 // whatever we want to do, we do it to the whole buffer 1339 VkImageSubresourceRange srRange = {}; 1340 srRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 1341 srRange.baseMipLevel = 0; 1342 srRange.levelCount = VK_REMAINING_MIP_LEVELS; 1343 srRange.baseArrayLayer = 0; 1344 srRange.layerCount = VK_REMAINING_ARRAY_LAYERS; 1345 1346 VkImageMemoryBarrier memory_barrier = {}; 1347 memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 1348 memory_barrier.srcAccessMask = output_mask; 1349 memory_barrier.dstAccessMask = input_mask; 1350 memory_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; 1351 memory_barrier.subresourceRange = srRange; 1352 VkImageMemoryBarrier *pmemory_barrier = &memory_barrier; 1353 1354 VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 1355 VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 1356 1357 for (i = 0; i < m_renderTargets.size(); i++) { 1358 memory_barrier.image = m_renderTargets[i]->image(); 1359 memory_barrier.oldLayout = m_renderTargets[i]->layout(); 1360 vkCmdPipelineBarrier(handle(), src_stages, dest_stages, 0, 0, NULL, 0, NULL, 1, pmemory_barrier); 1361 m_renderTargets[i]->layout(memory_barrier.newLayout); 1362 1363 vkCmdClearColorImage(handle(), m_renderTargets[i]->image(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &srRange); 1364 } 1365 1366 if (depthStencilObj) { 1367 VkImageSubresourceRange dsRange = {}; 1368 dsRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 1369 dsRange.baseMipLevel = 0; 1370 dsRange.levelCount = VK_REMAINING_MIP_LEVELS; 1371 dsRange.baseArrayLayer = 0; 1372 dsRange.layerCount = VK_REMAINING_ARRAY_LAYERS; 1373 1374 // prepare the depth buffer for clear 1375 1376 memory_barrier.oldLayout = memory_barrier.newLayout; 1377 memory_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; 1378 memory_barrier.image = depthStencilObj->handle(); 1379 memory_barrier.subresourceRange = dsRange; 1380 1381 vkCmdPipelineBarrier(handle(), src_stages, dest_stages, 0, 0, NULL, 0, NULL, 1, pmemory_barrier); 1382 1383 VkClearDepthStencilValue clear_value = {depth_clear_color, stencil_clear_color}; 1384 vkCmdClearDepthStencilImage(handle(), depthStencilObj->handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_value, 1, &dsRange); 1385 1386 // prepare depth buffer for rendering 1387 memory_barrier.image = depthStencilObj->handle(); 1388 memory_barrier.newLayout = memory_barrier.oldLayout; 1389 memory_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL; 1390 memory_barrier.subresourceRange = dsRange; 1391 vkCmdPipelineBarrier(handle(), src_stages, dest_stages, 0, 0, NULL, 0, NULL, 1, pmemory_barrier); 1392 } 1393 } 1394 1395 void VkCommandBufferObj::FillBuffer(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize fill_size, uint32_t data) { 1396 vkCmdFillBuffer(handle(), buffer, offset, fill_size, data); 1397 } 1398 1399 void VkCommandBufferObj::UpdateBuffer(VkBuffer buffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData) { 1400 vkCmdUpdateBuffer(handle(), buffer, dstOffset, dataSize, pData); 1401 } 1402 1403 void VkCommandBufferObj::CopyImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, 1404 uint32_t regionCount, const VkImageCopy *pRegions) { 1405 vkCmdCopyImage(handle(), srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions); 1406 } 1407 1408 void VkCommandBufferObj::ResolveImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, 1409 VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve *pRegions) { 1410 vkCmdResolveImage(handle(), srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions); 1411 } 1412 1413 void VkCommandBufferObj::PrepareAttachments() { 1414 uint32_t i; 1415 const VkFlags output_mask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 1416 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; 1417 const VkFlags input_mask = VK_ACCESS_HOST_READ_BIT | VK_ACCESS_INDIRECT_COMMAND_READ_BIT | VK_ACCESS_INDEX_READ_BIT | 1418 VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_UNIFORM_READ_BIT | VK_ACCESS_SHADER_READ_BIT | 1419 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | 1420 VK_ACCESS_MEMORY_READ_BIT; 1421 1422 VkImageSubresourceRange srRange = {}; 1423 srRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 1424 srRange.baseMipLevel = 0; 1425 srRange.levelCount = VK_REMAINING_MIP_LEVELS; 1426 srRange.baseArrayLayer = 0; 1427 srRange.layerCount = VK_REMAINING_ARRAY_LAYERS; 1428 1429 VkImageMemoryBarrier memory_barrier = {}; 1430 memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 1431 memory_barrier.srcAccessMask = output_mask; 1432 memory_barrier.dstAccessMask = input_mask; 1433 memory_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 1434 memory_barrier.subresourceRange = srRange; 1435 VkImageMemoryBarrier *pmemory_barrier = &memory_barrier; 1436 1437 VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 1438 VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 1439 1440 for (i = 0; i < m_renderTargets.size(); i++) { 1441 memory_barrier.image = m_renderTargets[i]->image(); 1442 memory_barrier.oldLayout = m_renderTargets[i]->layout(); 1443 vkCmdPipelineBarrier(handle(), src_stages, dest_stages, 0, 0, NULL, 0, NULL, 1, pmemory_barrier); 1444 m_renderTargets[i]->layout(memory_barrier.newLayout); 1445 } 1446 } 1447 1448 void VkCommandBufferObj::BeginRenderPass(const VkRenderPassBeginInfo &info) { 1449 vkCmdBeginRenderPass(handle(), &info, VK_SUBPASS_CONTENTS_INLINE); 1450 } 1451 1452 void VkCommandBufferObj::EndRenderPass() { vkCmdEndRenderPass(handle()); } 1453 1454 void VkCommandBufferObj::SetViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports) { 1455 vkCmdSetViewport(handle(), firstViewport, viewportCount, pViewports); 1456 } 1457 1458 void VkCommandBufferObj::SetScissor(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *pScissors) { 1459 vkCmdSetScissor(handle(), firstScissor, scissorCount, pScissors); 1460 } 1461 1462 void VkCommandBufferObj::SetLineWidth(float lineWidth) { vkCmdSetLineWidth(handle(), lineWidth); } 1463 1464 void VkCommandBufferObj::SetDepthBias(float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor) { 1465 vkCmdSetDepthBias(handle(), depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor); 1466 } 1467 1468 void VkCommandBufferObj::SetBlendConstants(const float blendConstants[4]) { vkCmdSetBlendConstants(handle(), blendConstants); } 1469 1470 void VkCommandBufferObj::SetDepthBounds(float minDepthBounds, float maxDepthBounds) { 1471 vkCmdSetDepthBounds(handle(), minDepthBounds, maxDepthBounds); 1472 } 1473 1474 void VkCommandBufferObj::SetStencilReadMask(VkStencilFaceFlags faceMask, uint32_t compareMask) { 1475 vkCmdSetStencilCompareMask(handle(), faceMask, compareMask); 1476 } 1477 1478 void VkCommandBufferObj::SetStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t writeMask) { 1479 vkCmdSetStencilWriteMask(handle(), faceMask, writeMask); 1480 } 1481 1482 void VkCommandBufferObj::SetStencilReference(VkStencilFaceFlags faceMask, uint32_t reference) { 1483 vkCmdSetStencilReference(handle(), faceMask, reference); 1484 } 1485 1486 void VkCommandBufferObj::AddRenderTarget(VkImageObj *renderTarget) { m_renderTargets.push_back(renderTarget); } 1487 1488 void VkCommandBufferObj::DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, 1489 uint32_t firstInstance) { 1490 vkCmdDrawIndexed(handle(), indexCount, instanceCount, firstIndex, vertexOffset, firstInstance); 1491 } 1492 1493 void VkCommandBufferObj::Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) { 1494 vkCmdDraw(handle(), vertexCount, instanceCount, firstVertex, firstInstance); 1495 } 1496 1497 void VkCommandBufferObj::QueueCommandBuffer(bool checkSuccess) { 1498 VkFence nullFence = {VK_NULL_HANDLE}; 1499 QueueCommandBuffer(nullFence, checkSuccess); 1500 } 1501 1502 void VkCommandBufferObj::QueueCommandBuffer(VkFence fence, bool checkSuccess) { 1503 VkResult err = VK_SUCCESS; 1504 1505 // submit the command buffer to the universal queue 1506 VkSubmitInfo submit_info; 1507 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 1508 submit_info.pNext = NULL; 1509 submit_info.waitSemaphoreCount = 0; 1510 submit_info.pWaitSemaphores = NULL; 1511 submit_info.pWaitDstStageMask = NULL; 1512 submit_info.commandBufferCount = 1; 1513 submit_info.pCommandBuffers = &handle(); 1514 submit_info.signalSemaphoreCount = 0; 1515 submit_info.pSignalSemaphores = NULL; 1516 1517 err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence); 1518 if (checkSuccess) { 1519 ASSERT_VK_SUCCESS(err); 1520 } 1521 1522 err = vkQueueWaitIdle(m_device->m_queue); 1523 if (checkSuccess) { 1524 ASSERT_VK_SUCCESS(err); 1525 } 1526 1527 // Wait for work to finish before cleaning up. 1528 vkDeviceWaitIdle(m_device->device()); 1529 } 1530 1531 void VkCommandBufferObj::BindPipeline(VkPipelineObj &pipeline) { 1532 vkCmdBindPipeline(handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.handle()); 1533 } 1534 1535 void VkCommandBufferObj::BindDescriptorSet(VkDescriptorSetObj &descriptorSet) { 1536 VkDescriptorSet set_obj = descriptorSet.GetDescriptorSetHandle(); 1537 1538 // bind pipeline, vertex buffer (descriptor set) and WVP (dynamic buffer 1539 // view) 1540 vkCmdBindDescriptorSets(handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, descriptorSet.GetPipelineLayout(), 0, 1, &set_obj, 0, NULL); 1541 } 1542 1543 void VkCommandBufferObj::BindIndexBuffer(VkIndexBufferObj *indexBuffer, VkDeviceSize offset) { 1544 vkCmdBindIndexBuffer(handle(), indexBuffer->handle(), offset, indexBuffer->GetIndexType()); 1545 } 1546 1547 void VkCommandBufferObj::BindVertexBuffer(VkConstantBufferObj *vertexBuffer, VkDeviceSize offset, uint32_t binding) { 1548 vkCmdBindVertexBuffers(handle(), binding, 1, &vertexBuffer->handle(), &offset); 1549 } 1550 1551 bool VkDepthStencilObj::Initialized() { return m_initialized; } 1552 VkDepthStencilObj::VkDepthStencilObj(VkDeviceObj *device) : VkImageObj(device) { m_initialized = false; } 1553 1554 VkImageView *VkDepthStencilObj::BindInfo() { return &m_attachmentBindInfo; } 1555 1556 void VkDepthStencilObj::Init(VkDeviceObj *device, int32_t width, int32_t height, VkFormat format, VkImageUsageFlags usage) { 1557 1558 VkImageViewCreateInfo view_info = {}; 1559 1560 m_device = device; 1561 m_initialized = true; 1562 m_depth_stencil_fmt = format; 1563 1564 /* create image */ 1565 init(width, height, m_depth_stencil_fmt, usage, VK_IMAGE_TILING_OPTIMAL); 1566 1567 VkImageAspectFlags aspect = VK_IMAGE_ASPECT_DEPTH_BIT; 1568 if (vk_format_is_depth_and_stencil(format)) 1569 aspect |= VK_IMAGE_ASPECT_STENCIL_BIT; 1570 1571 SetLayout(aspect, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); 1572 1573 view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 1574 view_info.pNext = NULL; 1575 view_info.image = VK_NULL_HANDLE; 1576 view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 1577 view_info.subresourceRange.baseMipLevel = 0; 1578 view_info.subresourceRange.levelCount = 1; 1579 view_info.subresourceRange.baseArrayLayer = 0; 1580 view_info.subresourceRange.layerCount = 1; 1581 view_info.flags = 0; 1582 view_info.format = m_depth_stencil_fmt; 1583 view_info.image = handle(); 1584 view_info.viewType = VK_IMAGE_VIEW_TYPE_2D; 1585 m_imageView.init(*m_device, view_info); 1586 1587 m_attachmentBindInfo = m_imageView.handle(); 1588 } 1589