void Image::copyImageToBuffer(const VkCommandBuffer cmdBuffer, IBufferSP& targetBuffer, const VkBufferImageCopy& bufferImageCopy) { if (!targetBuffer.get()) { return; } VkImageLayout sourceImageLayout = getImageLayout(bufferImageCopy.imageSubresource.mipLevel, bufferImageCopy.imageSubresource.baseArrayLayer); VkAccessFlags sourceAccessMask = getAccessMask(bufferImageCopy.imageSubresource.mipLevel, bufferImageCopy.imageSubresource.baseArrayLayer); VkAccessFlags targetAccessMask = targetBuffer->getAccessMask(); // Prepare source image for copy. VkImageSubresourceRange imageSubresourceRange = {bufferImageCopy.imageSubresource.aspectMask, bufferImageCopy.imageSubresource.mipLevel, 1, bufferImageCopy.imageSubresource.baseArrayLayer, bufferImageCopy.imageSubresource.layerCount}; cmdPipelineBarrier(cmdBuffer, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, imageSubresourceRange); // Prepare target buffer for copy. targetBuffer->cmdPipelineBarrier(cmdBuffer, VK_ACCESS_TRANSFER_WRITE_BIT); // Copy image by command. vkCmdCopyImageToBuffer(cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, targetBuffer->getBuffer(), 1, &bufferImageCopy); // Revert back. targetBuffer->cmdPipelineBarrier(cmdBuffer, targetAccessMask); // Revert back. cmdPipelineBarrier(cmdBuffer, sourceAccessMask, sourceImageLayout, imageSubresourceRange); }
IBufferObjectSP VKTS_APIENTRY bufferObjectCreate(IBufferSP& stageBuffer, IDeviceMemorySP& stageDeviceMemory, const IInitialResourcesSP& initialResources, const ICommandBuffersSP& cmdBuffer, const IBinaryBufferSP& binaryBuffer, const VkBufferCreateInfo& bufferCreateInfo, const VkMemoryPropertyFlags memoryPropertyFlag) { if (!initialResources.get() || !cmdBuffer.get() || !binaryBuffer.get()) { return IBufferObjectSP(); } // VkResult result; // IBufferSP buffer; IDeviceMemorySP deviceMemory; if (!bufferObjectPrepare(buffer, deviceMemory, initialResources, bufferCreateInfo, memoryPropertyFlag)) { return IBufferObjectSP(); } // if (memoryPropertyFlag & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { result = deviceMemory->upload(0, deviceMemory->getAllocationSize(), 0, binaryBuffer->getData(), binaryBuffer->getSize()); if (result != VK_SUCCESS) { logPrint(VKTS_LOG_ERROR, "BufferObject: Could not upload vertex data."); return IBufferObjectSP(); } } else { if (!bufferObjectPrepare(stageBuffer, stageDeviceMemory, initialResources, bufferCreateInfo, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) { logPrint(VKTS_LOG_ERROR, "BufferObject: Could not create vertex buffer."); return IBufferObjectSP(); } result = stageDeviceMemory->upload(0, stageDeviceMemory->getAllocationSize(), 0, binaryBuffer->getData(), binaryBuffer->getSize()); if (result != VK_SUCCESS) { logPrint(VKTS_LOG_ERROR, "BufferObject: Could not upload vertex data."); return IBufferObjectSP(); } VkBufferCopy bufferCopy; bufferCopy.srcOffset = 0; bufferCopy.dstOffset = 0; bufferCopy.size = binaryBuffer->getSize(); stageBuffer->copyBuffer(cmdBuffer->getCommandBuffer(), buffer->getBuffer(), buffer->getSize(), 1, &bufferCopy); } // IBufferViewSP noBufferView; auto newInstance = new BufferObject(initialResources, buffer, noBufferView, deviceMemory); if (!newInstance) { buffer->destroy(); return IBufferObjectSP(); } return IBufferObjectSP(newInstance); }
IBufferObjectSP VKTS_APIENTRY bufferObjectCreate(const IInitialResourcesSP& initialResources, const VkBufferCreateInfo& bufferCreateInfo, const VkMemoryPropertyFlags memoryPropertyFlag, const VkFormat format) { if (!initialResources.get()) { return IBufferObjectSP(); } // IBufferSP buffer; IDeviceMemorySP deviceMemory; if (!bufferObjectPrepare(buffer, deviceMemory, initialResources, bufferCreateInfo, memoryPropertyFlag)) { return IBufferObjectSP(); } // auto bufferView = bufferViewCreate(initialResources->getDevice()->getDevice(), 0, buffer->getBuffer(), format, 0, bufferCreateInfo.size); if (!bufferView.get()) { buffer->destroy(); return IBufferObjectSP(); } // auto newInstance = new BufferObject(initialResources, buffer, bufferView, deviceMemory); if (!newInstance) { bufferView->destroy(); buffer->destroy(); return IBufferObjectSP(); } return IBufferObjectSP(newInstance); }