Add imageData copying

This commit is contained in:
Bailey Harrison 2023-03-22 10:42:07 +00:00
parent 25ee640c41
commit fb57c7560e
2 changed files with 67 additions and 7 deletions

View File

@ -92,7 +92,12 @@ namespace engine {
}; };
renderData.setZeroBuffer = gfx()->createUniformBuffer(sizeof(RenderData::SetZeroBuffer), &initialSetZeroData); renderData.setZeroBuffer = gfx()->createUniformBuffer(sizeof(RenderData::SetZeroBuffer), &initialSetZeroData);
gfx()->updateDescriptorUniformBuffer(renderData.setZero, 0, renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer)); gfx()->updateDescriptorUniformBuffer(renderData.setZero, 0, renderData.setZeroBuffer, 0, sizeof(RenderData::SetZeroBuffer));
renderData.myImage = gfx()->createImage(512, 512, nullptr);
uint8_t* imageData = new uint8_t[512*512*4];
memset(imageData, (uint8_t)255u, 512*512*4);
renderData.myImage = gfx()->createImage(512, 512, imageData);
delete[] imageData;
renderData.mySampler = gfx()->createSampler(); renderData.mySampler = gfx()->createSampler();
gfx()->updateDescriptorCombinedImageSampler(renderData.setZero, 1, renderData.myImage, renderData.mySampler); gfx()->updateDescriptorCombinedImageSampler(renderData.setZero, 1, renderData.myImage, renderData.mySampler);

View File

@ -1269,14 +1269,40 @@ namespace engine {
delete buffer; delete buffer;
} }
// imageData must have pixel format R8G8B8A8_SRGB
gfx::Image* GFXDevice::createImage(uint32_t w, uint32_t h, const void* imageData) gfx::Image* GFXDevice::createImage(uint32_t w, uint32_t h, const void* imageData)
{ {
(void)imageData; assert(imageData != nullptr);
assert(pimpl->FRAMECOUNT == 0); assert(pimpl->FRAMECOUNT == 0);
gfx::Image* out = new gfx::Image{}; gfx::Image* out = new gfx::Image{};
VkBuffer stagingBuffer = VK_NULL_HANDLE;
VmaAllocation stagingAllocation = VK_NULL_HANDLE;
VkDeviceSize stagingBufferSize = (VkDeviceSize)w * (VkDeviceSize)h * 4;
/* create staging buffer */
{
VkBufferCreateInfo stagingBufferInfo{};
stagingBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
stagingBufferInfo.size = stagingBufferSize;
stagingBufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
stagingBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
stagingBufferInfo.flags = 0;
VmaAllocationCreateInfo stagingAllocInfo{};
stagingAllocInfo.usage = VMA_MEMORY_USAGE_AUTO;
stagingAllocInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
stagingAllocInfo.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
VKCHECK(vmaCreateBuffer(pimpl->allocator, &stagingBufferInfo, &stagingAllocInfo, &stagingBuffer, &stagingAllocation, nullptr));
void* dataDest;
VKCHECK(vmaMapMemory(pimpl->allocator, stagingAllocation, &dataDest));
memcpy(dataDest, imageData, stagingBufferSize);
vmaUnmapMemory(pimpl->allocator, stagingAllocation);
}
VkImageCreateInfo imageInfo{}; VkImageCreateInfo imageInfo{};
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageInfo.flags = 0; imageInfo.flags = 0;
@ -1333,12 +1359,12 @@ namespace engine {
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
barrier.srcStageMask = VK_PIPELINE_STAGE_2_NONE; barrier.srcStageMask = VK_PIPELINE_STAGE_2_NONE;
barrier.srcAccessMask = VK_ACCESS_2_NONE; barrier.srcAccessMask = VK_ACCESS_2_NONE;
barrier.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT; barrier.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
barrier.dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT; barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
barrier.srcQueueFamilyIndex = pimpl->device.queues.transferQueueFamily; barrier.srcQueueFamilyIndex = pimpl->device.queues.transferQueueFamily;
barrier.dstQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily; barrier.dstQueueFamilyIndex = pimpl->device.queues.transferQueueFamily;
barrier.image = out->image; barrier.image = out->image;
barrier.subresourceRange = viewInfo.subresourceRange; barrier.subresourceRange = viewInfo.subresourceRange;
@ -1349,6 +1375,33 @@ namespace engine {
vkCmdPipelineBarrier2(commandBuffer, &depInfo); vkCmdPipelineBarrier2(commandBuffer, &depInfo);
VkBufferImageCopy region{};
region.bufferOffset = 0;
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
region.imageSubresource.aspectMask = viewInfo.subresourceRange.aspectMask;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageOffset.x = 0;
region.imageOffset.y = 0;
region.imageOffset.z = 0;
region.imageExtent = imageInfo.extent;
vkCmdCopyBufferToImage(commandBuffer, stagingBuffer, out->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
// Re-use old struct, only changing some values
barrier.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
barrier.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT;
barrier.dstAccessMask = VK_ACCESS_2_SHADER_SAMPLED_READ_BIT;
barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
barrier.srcQueueFamilyIndex = pimpl->device.queues.transferQueueFamily;
barrier.dstQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
vkCmdPipelineBarrier2(commandBuffer, &depInfo);
VKCHECK(vkEndCommandBuffer(commandBuffer)); VKCHECK(vkEndCommandBuffer(commandBuffer));
} }
@ -1364,6 +1417,8 @@ namespace engine {
vkFreeCommandBuffers(pimpl->device.device, pimpl->transferCommandPool, 1, &commandBuffer); vkFreeCommandBuffers(pimpl->device.device, pimpl->transferCommandPool, 1, &commandBuffer);
vmaDestroyBuffer(pimpl->allocator, stagingBuffer, stagingAllocation);
return out; return out;
} }