void vkeGameRendererDynamic::setNodeData(VkeNodeData::List *inData){ m_node_data = inData; if (m_node_data != NULL){ uint32_t cnt = m_node_data->count(); uint32_t transformsSize = 64 * 64; uint32_t sz = sizeof(VkeNodeUniform) * 100; sz += (transformsSize); VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; bufferCreate(&m_uniforms_buffer_staging, sz, (VkBufferUsageFlagBits)usageFlags); bufferAlloc(&m_uniforms_buffer_staging, &m_uniforms_staging, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); bufferCreate(&m_uniforms_buffer, sz, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); bufferAlloc(&m_uniforms_buffer, &m_uniforms_memory, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); m_uniforms_descriptor.buffer = m_uniforms_buffer; m_uniforms_descriptor.offset = 0; m_uniforms_descriptor.range = sizeof(VkeNodeUniform) * 100; m_transforms_descriptor.buffer = m_uniforms_buffer; m_transforms_descriptor.offset = sizeof(VkeNodeUniform) * 100; m_transforms_descriptor.range = transformsSize; //(4 * 64); } }
void vkeGameRendererDynamic::setMaterialData(VkeMaterial::List *inData){ m_materials = inData; if (m_materials != NULL){ uint32_t cnt = m_materials->count(); uint32_t sz = sizeof(VkeMaterialUniform) * cnt; VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; bufferCreate(&m_material_buffer_staging, sz, (VkBufferUsageFlagBits)usageFlags); bufferAlloc(&m_material_buffer_staging, &m_material_staging, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT); VkeMaterialUniform *uniforms = NULL; VKA_CHECK_ERROR(vkMapMemory(getDefaultDevice(), m_material_staging, 0, sz, 0, (void **)&uniforms), "Could not map buffer memory.\n"); for (uint32_t i = 0; i < cnt; ++i){ VkeMaterial *mat = m_materials->getMaterial(i); mat->initVKBufferData(m_material_buffer_staging); mat->updateVKBufferData(uniforms); } vkUnmapMemory(getDefaultDevice(), m_material_staging); } }
void vkeGameRendererDynamic::setNodeData(VkeNodeData::List *inData){ m_node_data = inData; if (m_node_data != NULL){ uint32_t cnt = m_node_data->count(); uint32_t transformsSize = 64 * m_instance_count; uint32_t sz = sizeof(VkeNodeUniform) * cnt; sz += (transformsSize); m_uniforms_local = (float*)malloc( sz); bufferCreate(&m_uniforms_buffer, sz, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); bufferAlloc(&m_uniforms_buffer, &m_uniforms_memory, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); m_uniforms_descriptor.buffer = m_uniforms_buffer; m_uniforms_descriptor.offset = 0; m_uniforms_descriptor.range = sizeof(VkeNodeUniform) * cnt; m_transforms_descriptor.buffer = m_uniforms_buffer; m_transforms_descriptor.offset = sizeof(VkeNodeUniform) * cnt; m_transforms_descriptor.range = transformsSize; } }
/** * Sends a packet of bytes to a remote peer. Returns 0 on success. * * Returns -1 if an error occurs. Sets errno to ENOMEM if memory couldn't be * allocated. Sets errno to EHOSTDOWN if the peer died recently. Sets errno * to EINVAL if pid is the same as the local pid. */ int peerSendBytes(pid_t pid, const char* bytes, size_t size) { Peer* peer = localPeer; assert(peer != NULL); OutgoingPacket* packet = calloc(1, sizeof(OutgoingPacket)); if (packet == NULL) { errno = ENOMEM; return -1; } Buffer* copy = bufferCreate(size); if (copy == NULL) { free(packet); errno = ENOMEM; return -1; } // Copy data. memcpy(copy->data, bytes, size); copy->size = size; packet->bytes = copy; packet->header.type = BYTES; packet->header.size = size; packet->free = outgoingPacketFreeBytes; bufferPrepareForWrite(packet->bytes); peerLock(peer); PeerProxy* peerProxy = peerProxyGetOrCreate(peer, pid, true); if (peerProxy == NULL) { // The peer is already dead or we couldn't alloc memory. Either way, // errno is set. peerUnlock(peer); packet->free(packet); return -1; } else { peerProxyEnqueueOutgoingPacket(peerProxy, packet); peerUnlock(peer); selectorWakeUp(peer->selector); return 0; } }
static VkBool32 bufferObjectPrepare(IBufferSP& buffer, IDeviceMemorySP& deviceMemory, const IInitialResourcesSP& initialResources, const VkBufferCreateInfo& bufferCreateInfo, const VkMemoryPropertyFlags memoryPropertyFlag) { VkResult result; // buffer = bufferCreate(initialResources->getDevice()->getDevice(), bufferCreateInfo.flags, bufferCreateInfo.size, bufferCreateInfo.usage, bufferCreateInfo.sharingMode, bufferCreateInfo.queueFamilyIndexCount, bufferCreateInfo.pQueueFamilyIndices); if (!buffer.get()) { logPrint(VKTS_LOG_ERROR, "BufferObject: Could not create buffer."); return VK_FALSE; } VkMemoryRequirements memoryRequirements; buffer->getBufferMemoryRequirements(memoryRequirements); VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProperties; initialResources->getPhysicalDevice()->getPhysicalDeviceMemoryProperties(physicalDeviceMemoryProperties); deviceMemory = deviceMemoryCreate(initialResources->getDevice()->getDevice(), memoryRequirements, physicalDeviceMemoryProperties.memoryTypeCount, physicalDeviceMemoryProperties.memoryTypes, memoryPropertyFlag); if (!deviceMemory.get()) { logPrint(VKTS_LOG_ERROR, "BufferObject: Could not allocate memory."); return VK_FALSE; } result = buffer->bindBufferMemory(deviceMemory->getDeviceMemory(), 0); if (result != VK_SUCCESS) { logPrint(VKTS_LOG_ERROR, "BufferObject: Could not bind buffer memory."); return VK_FALSE; } return VK_TRUE; }
static PeerProxy* peerProxyCreate(Peer* peer, Credentials credentials) { PeerProxy* peerProxy = calloc(1, sizeof(PeerProxy)); if (peerProxy == NULL) { return NULL; } peerProxy->inputBuffer = bufferCreate(sizeof(Header)); if (peerProxy->inputBuffer == NULL) { free(peerProxy); return NULL; } peerProxy->peer = peer; peerProxy->credentials = credentials; // Initial state == expecting a header. peerProxyExpectHeader(peerProxy); // Add this proxy to the map. Make sure the key points to the stable memory // inside of the peer proxy itself. pid_t* pid = &(peerProxy->credentials.pid); hashmapPut(peer->peerProxies, pid, peerProxy); return peerProxy; }
void VkeCubeTexture::loadCubeDDS(const char *inFile){ std::string searchPaths[] = { std::string(PROJECT_NAME), NVPWindow::sysExePath() + std::string(PROJECT_RELDIRECTORY), std::string(PROJECT_ABSDIRECTORY) }; nv_dds::CDDSImage ddsImage; for (uint32_t i = 0; i < 3; ++i){ std::string separator = ""; uint32_t strSize = searchPaths[i].size(); if(searchPaths[i].substr(strSize-1,strSize) != "/") separator = "/"; std::string filePath = searchPaths[i] + separator + std::string("images/") + std::string(inFile); ddsImage.load(filePath, true); if (ddsImage.is_valid()) break; } if (!ddsImage.is_valid()){ perror("Could not cube load texture image.\n"); exit(1); } uint32_t imgW = ddsImage.get_width(); uint32_t imgH = ddsImage.get_height(); uint32_t comCount = ddsImage.get_components(); uint32_t fmt = ddsImage.get_format(); bool isCube = ddsImage.is_cubemap(); bool isComp = ddsImage.is_compressed(); VkFormat vkFmt = VK_FORMAT_R8G8B8A8_UNORM; switch (fmt){ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: vkFmt = VK_FORMAT_BC1_RGB_SRGB_BLOCK; break; case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: vkFmt = VK_FORMAT_BC2_UNORM_BLOCK; break; case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: vkFmt = VK_FORMAT_BC3_UNORM_BLOCK; break; default: break; } m_width = imgW; m_height = imgH; m_format = vkFmt; VulkanDC::Device::Queue::Name queueName = "DEFAULT_GRAPHICS_QUEUE"; VulkanDC::Device::Queue::CommandBufferID cmdID = INIT_COMMAND_ID; VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDefaultDevice(); VulkanDC::Device::Queue *queue = device->getQueue(queueName); VkCommandBuffer cmd = VK_NULL_HANDLE; queue->beginCommandBuffer(cmdID, &cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); imageCreateAndBind( &m_data.image, &m_data.memory, m_format, VK_IMAGE_TYPE_2D, m_width, m_height, 1, 6, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, (VkImageUsageFlagBits)(VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT), VK_IMAGE_TILING_OPTIMAL); VkBuffer cubeMapBuffer; VkDeviceMemory cubeMapMem; bufferCreate(&cubeMapBuffer, m_width*m_height * 3 * 6, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); bufferAlloc(&cubeMapBuffer, &cubeMapMem, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); if (m_memory_flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT){ imageSetLayoutBarrier(cmdID, queueName, m_data.image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED, VK_IMAGE_LAYOUT_GENERAL); for (uint32_t i = 0; i < 6; ++i){ void *data = NULL; VkSubresourceLayout layout; VkImageSubresource subres; subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; subres.mipLevel = m_mip_level; subres.arrayLayer = i; vkGetImageSubresourceLayout(getDefaultDevice(), m_data.image, &subres, &layout); VKA_CHECK_ERROR(vkMapMemory(getDefaultDevice(), cubeMapMem, layout.offset, layout.size, 0, &data), "Could not map memory for image.\n"); const nv_dds::CTexture &mipmap = ddsImage.get_cubemap_face(i); memcpy(data, (void *)mipmap, layout.size); vkUnmapMemory(getDefaultDevice(), cubeMapMem); } VkBufferImageCopy biCpyRgn[6]; for (uint32_t k = 0; k < 6; ++k){ VkSubresourceLayout layout; VkImageSubresource subres; subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; subres.mipLevel = m_mip_level; subres.arrayLayer = k; vkGetImageSubresourceLayout(getDefaultDevice(), m_data.image, &subres, &layout); biCpyRgn[k].bufferOffset = layout.offset; biCpyRgn[k].bufferImageHeight = 0; biCpyRgn[k].bufferRowLength = 0; biCpyRgn[k].imageExtent.width = m_width; biCpyRgn[k].imageExtent.height = m_height; biCpyRgn[k].imageExtent.depth = 1; biCpyRgn[k].imageOffset.x = 0; biCpyRgn[k].imageOffset.y = 0; biCpyRgn[k].imageOffset.z = 0; biCpyRgn[k].imageSubresource.baseArrayLayer = k; biCpyRgn[k].imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; biCpyRgn[k].imageSubresource.layerCount = 1; biCpyRgn[k].imageSubresource.mipLevel = 0; } VkFence copyFence; VkFenceCreateInfo fenceInfo; memset(&fenceInfo, 0, sizeof(fenceInfo)); fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; vkCreateFence(device->getVKDevice(), &fenceInfo, NULL, ©Fence); vkCmdCopyBufferToImage(cmd, cubeMapBuffer, m_data.image, m_data.imageLayout, 6, biCpyRgn); queue->flushCommandBuffer(cmdID, ©Fence); vkWaitForFences(device->getVKDevice(), 1, ©Fence, VK_TRUE, 100000000000); vkDestroyBuffer(device->getVKDevice(), cubeMapBuffer, NULL); vkFreeMemory(device->getVKDevice(), cubeMapMem, NULL); } VkSamplerCreateInfo sampler; sampler.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; sampler.pNext = NULL; sampler.magFilter = VK_FILTER_NEAREST; sampler.minFilter = VK_FILTER_NEAREST; sampler.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sampler.mipLodBias = 0.0f; sampler.maxAnisotropy = 1; sampler.compareOp = VK_COMPARE_OP_NEVER; sampler.minLod = 0.0f; sampler.maxLod = 0.0f; sampler.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; VkImageViewCreateInfo view; view.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; view.pNext = NULL; view.viewType = VK_IMAGE_VIEW_TYPE_CUBE; view.format = m_format; view.components.r = VK_COMPONENT_SWIZZLE_R; view.components.g = VK_COMPONENT_SWIZZLE_G; view.components.b = VK_COMPONENT_SWIZZLE_B; view.components.a = VK_COMPONENT_SWIZZLE_A; view.subresourceRange.baseArrayLayer = 0; view.subresourceRange.levelCount = 1; view.subresourceRange.baseMipLevel = 0; view.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; view.subresourceRange.layerCount = 1; VKA_CHECK_ERROR(vkCreateSampler(getDefaultDevice(), &sampler, NULL, &m_data.sampler), "Could not create sampler for image texture.\n"); view.image = m_data.image; VKA_CHECK_ERROR(vkCreateImageView(getDefaultDevice(), &view, NULL, &m_data.view), "Could not create image view for texture.\n"); }
void VkeCubeTexture::loadTextureFiles(const char **inPath){ bool imagesOK = true; VKA_INFO_MSG("Loading Cube Texture.\n"); for (uint32_t i = 0; i < 6; ++i){ if (!loadTexture(inPath[i], NULL, NULL, &m_width, &m_height)){ VKA_ERROR_MSG("Error loading texture image.\n"); printf("Texture : %d not available (%s).\n", i, inPath[i]); return; } } VulkanDC::Device::Queue::Name queueName = "DEFAULT_GRAPHICS_QUEUE"; VulkanDC::Device::Queue::CommandBufferID cmdID = INIT_COMMAND_ID; VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDefaultDevice(); VulkanDC::Device::Queue *queue = device->getQueue(queueName); VkCommandBuffer cmd = VK_NULL_HANDLE; queue->beginCommandBuffer(cmdID, &cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); imageCreateAndBind( &m_data.image, &m_data.memory, m_format, VK_IMAGE_TYPE_2D, m_width, m_height, 1, 6, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, (VkImageUsageFlagBits)( VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT ), VK_IMAGE_TILING_OPTIMAL); VkBuffer cubeMapBuffer; VkDeviceMemory cubeMapMem; bufferCreate(&cubeMapBuffer, m_width*m_height * 4 * 6, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); bufferAlloc(&cubeMapBuffer, &cubeMapMem, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); VkDeviceSize dSize = m_width * m_height * 4; uint32_t rowPitch = m_width * 4; if (m_memory_flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT){ imageSetLayoutBarrier(cmdID, queueName, m_data.image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED, VK_IMAGE_LAYOUT_GENERAL); for (uint32_t i = 0; i < 6; ++i){ void *data = NULL; VkDeviceSize ofst = dSize*i; VKA_CHECK_ERROR(vkMapMemory(getDefaultDevice(),cubeMapMem, ofst, dSize, 0, &data), "Could not map memory for image.\n"); if (!loadTexture(inPath[i], (uint8_t**)&data, rowPitch, &m_width, &m_height)){ VKA_ERROR_MSG("Could not load final image.\n"); } vkUnmapMemory(getDefaultDevice(), cubeMapMem); } VkBufferImageCopy biCpyRgn[6]; for (uint32_t k = 0; k < 6; ++k){ VkDeviceSize ofst = dSize*k; biCpyRgn[k].bufferOffset = ofst; biCpyRgn[k].bufferImageHeight = 0; biCpyRgn[k].bufferRowLength = 0; biCpyRgn[k].imageExtent.width = m_width; biCpyRgn[k].imageExtent.height = m_height; biCpyRgn[k].imageExtent.depth = 1; biCpyRgn[k].imageOffset.x = 0; biCpyRgn[k].imageOffset.y = 0; biCpyRgn[k].imageOffset.z = 0; biCpyRgn[k].imageSubresource.baseArrayLayer = k; biCpyRgn[k].imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; biCpyRgn[k].imageSubresource.layerCount = 1; biCpyRgn[k].imageSubresource.mipLevel = 0; } VkFence copyFence; VkFenceCreateInfo fenceInfo; memset(&fenceInfo, 0, sizeof(fenceInfo)); fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; vkCreateFence(device->getVKDevice(), &fenceInfo,NULL , ©Fence); vkCmdCopyBufferToImage(cmd, cubeMapBuffer, m_data.image, m_data.imageLayout, 6, biCpyRgn); queue->flushCommandBuffer(cmdID , ©Fence); vkWaitForFences(device->getVKDevice(), 1, ©Fence, VK_TRUE, 100000000000); vkDestroyBuffer(device->getVKDevice(), cubeMapBuffer, NULL); vkFreeMemory(device->getVKDevice(), cubeMapMem, NULL); } VkSamplerCreateInfo sampler; sampler.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; sampler.pNext = NULL; sampler.magFilter = VK_FILTER_NEAREST; sampler.minFilter = VK_FILTER_NEAREST; sampler.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sampler.mipLodBias = 0.0f; sampler.maxAnisotropy = 1; sampler.compareOp = VK_COMPARE_OP_NEVER; sampler.minLod = 0.0f; sampler.maxLod = 0.0f; sampler.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; VkImageViewCreateInfo view; view.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; view.pNext = NULL; view.viewType = VK_IMAGE_VIEW_TYPE_CUBE; view.format = m_format; view.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; view.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 0 }; view.subresourceRange.baseArrayLayer = 0; view.subresourceRange.levelCount = 1; view.subresourceRange.baseMipLevel = 0; view.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; view.subresourceRange.layerCount = 1; VKA_CHECK_ERROR(vkCreateSampler(getDefaultDevice(), &sampler,NULL, &m_data.sampler), "Could not create sampler for image texture.\n"); view.image = m_data.image; VKA_CHECK_ERROR(vkCreateImageView(getDefaultDevice(), &view,NULL, &m_data.view), "Could not create image view for texture.\n"); VKA_INFO_MSG("Created CUBE Image Texture.\n"); }
void vkeGameRendererDynamic::initIndirectCommands(){ if (!m_node_data) return; VulkanDC *dc = VulkanDC::Get(); VulkanDC::Device *device = dc->getDefaultDevice(); VulkanDC::Device::Queue *queue = dc->getDefaultQueue(); uint32_t cnt = m_node_data->count(); uint32_t sz = sizeof(VkDrawIndexedIndirectCommand)*cnt; VkBuffer sceneIndirectStaging; VkDeviceMemory sceneIndirectMemStaging; VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; bufferCreate(&m_scene_indirect_buffer, sz, (VkBufferUsageFlagBits)usageFlags); bufferAlloc(&m_scene_indirect_buffer, &m_scene_indirect_memory, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); usageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; bufferCreate(&sceneIndirectStaging, sz, (VkBufferUsageFlagBits)usageFlags); bufferAlloc(&sceneIndirectStaging, &sceneIndirectMemStaging, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); VkDrawIndexedIndirectCommand *commands = NULL; VKA_CHECK_ERROR(vkMapMemory(device->getVKDevice(), sceneIndirectMemStaging, 0, sz, 0, (void **)&commands), "Could not map indirect buffer memory.\n"); for (uint32_t i = 0; i < cnt; ++i){ VkeMesh *mesh = m_node_data->getData(i)->getMesh(); commands[i].firstIndex = mesh->getFirstIndex(); commands[i].firstInstance = i*m_instance_count; commands[i].vertexOffset = mesh->getFirstVertex(); commands[i].indexCount = mesh->getIndexCount(); commands[i].instanceCount = m_instance_count; } vkUnmapMemory(device->getVKDevice(), sceneIndirectMemStaging); VkBufferCopy bufCpy; bufCpy.dstOffset = 0; bufCpy.srcOffset = 0; bufCpy.size = sz; VkCommandBuffer copyCmd; VkCommandBufferAllocateInfo cmdBufInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; cmdBufInfo.commandBufferCount = 1; cmdBufInfo.commandPool = queue->getCommandPool(); cmdBufInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; VKA_CHECK_ERROR(vkAllocateCommandBuffers(device->getVKDevice(), &cmdBufInfo, ©Cmd), "Could not allocate command buffers.\n"); VkCommandBufferBeginInfo cmdBeginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; cmdBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; VKA_CHECK_ERROR(vkBeginCommandBuffer(copyCmd, &cmdBeginInfo), "Could not begin commmand buffer.\n"); vkCmdCopyBuffer(copyCmd, sceneIndirectStaging, m_scene_indirect_buffer, 1, &bufCpy); VKA_CHECK_ERROR(vkEndCommandBuffer(copyCmd), "Could not end command buffer.\n"); VkSubmitInfo subInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO }; subInfo.commandBufferCount = 1; subInfo.pCommandBuffers = ©Cmd; VkFence theFence; VkFenceCreateInfo fenceInfo = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; VKA_CHECK_ERROR(vkCreateFence(device->getVKDevice(), &fenceInfo, NULL, &theFence), "Could not create fence.\n"); VKA_CHECK_ERROR(vkQueueSubmit(queue->getVKQueue(), 1, &subInfo, theFence), "Could not submit queue for indirect buffer copy.\n"); VKA_CHECK_ERROR(vkWaitForFences(device->getVKDevice(), 1, &theFence, VK_TRUE, UINT_MAX), "Could not wait for fence.\n"); vkFreeCommandBuffers(device->getVKDevice(), queue->getCommandPool(), 1, ©Cmd); vkDestroyFence(device->getVKDevice(), theFence, NULL); }