mirror of
https://github.com/love2d/love.git
synced 2026-08-17 19:23:38 +02:00
vulkan: add missing layout transitions
This commit is contained in:
@@ -44,7 +44,9 @@ bool Texture::loadVolatile() {
|
|||||||
throw love::Exception("failed to create image");
|
throw love::Exception("failed to create image");
|
||||||
}
|
}
|
||||||
// fixme: we should use VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL as the default image layout instead of VK_IMAGE_LAYOUT_GENERAL.
|
// fixme: we should use VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL as the default image layout instead of VK_IMAGE_LAYOUT_GENERAL.
|
||||||
transitionImageLayout(textureImage, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
|
vgfx->queueDatatransfer([textureImage = textureImage](VkCommandBuffer commandBuffer){
|
||||||
|
Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
|
||||||
|
}, nullptr);
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
auto sliceData = data->get(0, 0);
|
auto sliceData = data->get(0, 0);
|
||||||
@@ -211,14 +213,6 @@ VkClearColorValue Texture::getClearValue(bool white) {
|
|||||||
return clearColor;
|
return clearColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::transitionImageLayout(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout) {
|
|
||||||
auto commandBuffer = vgfx->beginSingleTimeCommands();
|
|
||||||
|
|
||||||
Vulkan::cmdTransitionImageLayout(commandBuffer, image, oldLayout, newLayout);
|
|
||||||
|
|
||||||
vgfx->endSingleTimeCommands(commandBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::uploadByteData(PixelFormat pixelformat, const void* data, size_t size, int level, int slice, const Rect& r) {
|
void Texture::uploadByteData(PixelFormat pixelformat, const void* data, size_t size, int level, int slice, const Rect& r) {
|
||||||
VkBuffer stagingBuffer;
|
VkBuffer stagingBuffer;
|
||||||
VmaAllocation vmaAllocation;
|
VmaAllocation vmaAllocation;
|
||||||
@@ -291,7 +285,11 @@ void Texture::copyFromBuffer(graphics::Buffer* source, size_t sourceoffset, int
|
|||||||
region.imageExtent.width = static_cast<uint32_t>(rect.w);
|
region.imageExtent.width = static_cast<uint32_t>(rect.w);
|
||||||
region.imageExtent.height = static_cast<uint32_t>(rect.h);
|
region.imageExtent.height = static_cast<uint32_t>(rect.h);
|
||||||
|
|
||||||
|
Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
|
|
||||||
vkCmdCopyBufferToImage(commandBuffer, (VkBuffer)source->getHandle(), textureImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
vkCmdCopyBufferToImage(commandBuffer, (VkBuffer)source->getHandle(), textureImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||||
|
|
||||||
|
Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL);
|
||||||
}, nullptr);
|
}, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,7 +309,11 @@ void Texture::copyToBuffer(graphics::Buffer* dest, int slice, int mipmap, const
|
|||||||
region.imageExtent.width = static_cast<uint32_t>(rect.w);
|
region.imageExtent.width = static_cast<uint32_t>(rect.w);
|
||||||
region.imageExtent.height = static_cast<uint32_t>(rect.h);
|
region.imageExtent.height = static_cast<uint32_t>(rect.h);
|
||||||
|
|
||||||
|
Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||||
|
|
||||||
vkCmdCopyImageToBuffer(commandBuffer, textureImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, (VkBuffer) dest->getHandle(), 1, ®ion);
|
vkCmdCopyImageToBuffer(commandBuffer, textureImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, (VkBuffer) dest->getHandle(), 1, ®ion);
|
||||||
|
|
||||||
|
Vulkan::cmdTransitionImageLayout(commandBuffer, textureImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL);
|
||||||
}, nullptr);
|
}, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ public:
|
|||||||
VkSampler getSampler() const { return textureSampler; }
|
VkSampler getSampler() const { return textureSampler; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void transitionImageLayout(VkImage, VkImageLayout oldLayout, VkImageLayout newLayout);
|
|
||||||
void createTextureImageView();
|
void createTextureImageView();
|
||||||
void createTextureSampler();
|
void createTextureSampler();
|
||||||
void clear(bool white);
|
void clear(bool white);
|
||||||
|
|||||||
@@ -533,6 +533,20 @@ void Vulkan::cmdTransitionImageLayout(VkCommandBuffer commandBuffer, VkImage ima
|
|||||||
sourceStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
sourceStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
destinationStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
destinationStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||||
}
|
}
|
||||||
|
else if (oldLayout == VK_IMAGE_LAYOUT_GENERAL && newLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) {
|
||||||
|
barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||||
|
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||||
|
|
||||||
|
sourceStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||||
|
destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||||
|
}
|
||||||
|
else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_GENERAL) {
|
||||||
|
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||||
|
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||||
|
|
||||||
|
sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||||
|
destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
throw std::invalid_argument("unsupported layout transition!");
|
throw std::invalid_argument("unsupported layout transition!");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user