mirror of
https://github.com/love2d/love.git
synced 2026-08-20 04:30:09 +02:00
working text rendering
This commit is contained in:
@@ -1099,7 +1099,7 @@ namespace love {
|
|||||||
bufferInfo.range = sizeof(graphics::Shader::BuiltinUniformData);
|
bufferInfo.range = sizeof(graphics::Shader::BuiltinUniformData);
|
||||||
|
|
||||||
VkDescriptorImageInfo imageInfo{};
|
VkDescriptorImageInfo imageInfo{};
|
||||||
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
imageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||||
Texture* vkTexture = (Texture*)config.texture;
|
Texture* vkTexture = (Texture*)config.texture;
|
||||||
imageInfo.imageView = vkTexture->getImageView();
|
imageInfo.imageView = vkTexture->getImageView();
|
||||||
imageInfo.sampler = vkTexture->getSampler();
|
imageInfo.sampler = vkTexture->getSampler();
|
||||||
|
|||||||
@@ -13,6 +13,31 @@ namespace love {
|
|||||||
allocator = vgfx->getVmaAllocator();
|
allocator = vgfx->getVmaAllocator();
|
||||||
device = vgfx->getDevice();
|
device = vgfx->getDevice();
|
||||||
|
|
||||||
|
auto vulkanFormat = Vulkan::getTextureFormat(format);
|
||||||
|
|
||||||
|
VkImageCreateInfo imageInfo{};
|
||||||
|
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||||
|
imageInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||||
|
imageInfo.extent.width = static_cast<uint32_t>(width);
|
||||||
|
imageInfo.extent.height = static_cast<uint32_t>(height);
|
||||||
|
imageInfo.extent.depth = 1;
|
||||||
|
imageInfo.mipLevels = 1;
|
||||||
|
imageInfo.arrayLayers = 1;
|
||||||
|
imageInfo.format = vulkanFormat.internalFormat;
|
||||||
|
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
|
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
|
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
|
||||||
|
VmaAllocationCreateInfo imageAllocationCreateInfo{};
|
||||||
|
|
||||||
|
if (vmaCreateImage(allocator, &imageInfo, &imageAllocationCreateInfo, &textureImage, &textureImageAllocation, nullptr) != VK_SUCCESS) {
|
||||||
|
throw love::Exception("failed to create image");
|
||||||
|
}
|
||||||
|
// fixme: is there a way we don't use the general image layout?
|
||||||
|
transitionImageLayout(textureImage, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
auto sliceData = data->get(0, 0);
|
auto sliceData = data->get(0, 0);
|
||||||
auto size = sliceData->getSize();
|
auto size = sliceData->getSize();
|
||||||
@@ -91,7 +116,7 @@ namespace love {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout) {
|
void Texture::transitionImageLayout(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout) {
|
||||||
auto commandBuffer = vgfx->beginSingleTimeCommands();
|
auto commandBuffer = vgfx->beginSingleTimeCommands();
|
||||||
|
|
||||||
VkPipelineStageFlags sourceStage;
|
VkPipelineStageFlags sourceStage;
|
||||||
@@ -123,6 +148,20 @@ namespace love {
|
|||||||
sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||||
destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||||
}
|
}
|
||||||
|
else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_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 if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_GENERAL) {
|
||||||
|
barrier.srcAccessMask = 0;
|
||||||
|
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
|
||||||
|
|
||||||
|
sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||||
|
destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
throw love::Exception("unsupported lay transition");
|
throw love::Exception("unsupported lay transition");
|
||||||
}
|
}
|
||||||
@@ -139,7 +178,7 @@ namespace love {
|
|||||||
vgfx->endSingleTimeCommands(commandBuffer);
|
vgfx->endSingleTimeCommands(commandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height) {
|
void Texture::copyBufferToImage(VkBuffer buffer, VkImage image, const Rect& r) {
|
||||||
auto commandBuffer = vgfx->beginSingleTimeCommands();
|
auto commandBuffer = vgfx->beginSingleTimeCommands();
|
||||||
|
|
||||||
VkBufferImageCopy region{};
|
VkBufferImageCopy region{};
|
||||||
@@ -152,17 +191,17 @@ namespace love {
|
|||||||
region.imageSubresource.baseArrayLayer = 0;
|
region.imageSubresource.baseArrayLayer = 0;
|
||||||
region.imageSubresource.layerCount = 1;
|
region.imageSubresource.layerCount = 1;
|
||||||
|
|
||||||
region.imageOffset = { 0, 0, 0 };
|
region.imageOffset = { r.x, r.y, 0 };
|
||||||
region.imageExtent = {
|
region.imageExtent = {
|
||||||
width,
|
static_cast<uint32_t>(r.w),
|
||||||
height, 1
|
static_cast<uint32_t>(r.h), 1
|
||||||
};
|
};
|
||||||
|
|
||||||
vkCmdCopyBufferToImage(
|
vkCmdCopyBufferToImage(
|
||||||
commandBuffer,
|
commandBuffer,
|
||||||
buffer,
|
buffer,
|
||||||
image,
|
image,
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
VK_IMAGE_LAYOUT_GENERAL,
|
||||||
1,
|
1,
|
||||||
®ion
|
®ion
|
||||||
);
|
);
|
||||||
@@ -171,8 +210,6 @@ namespace love {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
format = pixelformat;
|
|
||||||
|
|
||||||
VkBuffer stagingBuffer;
|
VkBuffer stagingBuffer;
|
||||||
VmaAllocation vmaAllocation;
|
VmaAllocation vmaAllocation;
|
||||||
|
|
||||||
@@ -190,32 +227,7 @@ namespace love {
|
|||||||
|
|
||||||
memcpy(allocInfo.pMappedData, data, size);
|
memcpy(allocInfo.pMappedData, data, size);
|
||||||
|
|
||||||
auto vulkanFormat = Vulkan::getTextureFormat(format);
|
copyBufferToImage(stagingBuffer, textureImage, r);
|
||||||
|
|
||||||
VkImageCreateInfo imageInfo{};
|
|
||||||
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
|
||||||
imageInfo.imageType = VK_IMAGE_TYPE_2D;
|
|
||||||
imageInfo.extent.width = static_cast<uint32_t>(r.w);
|
|
||||||
imageInfo.extent.height = static_cast<uint32_t>(r.h);
|
|
||||||
imageInfo.extent.depth = 1;
|
|
||||||
imageInfo.mipLevels = 1;
|
|
||||||
imageInfo.arrayLayers = 1;
|
|
||||||
imageInfo.format = vulkanFormat.internalFormat;
|
|
||||||
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
|
||||||
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
||||||
imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
|
||||||
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
||||||
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
|
|
||||||
VmaAllocationCreateInfo imageAllocationCreateInfo{};
|
|
||||||
|
|
||||||
if (vmaCreateImage(allocator, &imageInfo, &imageAllocationCreateInfo, &textureImage, &textureImageAllocation, nullptr) != VK_SUCCESS) {
|
|
||||||
throw love::Exception("failed to create image");
|
|
||||||
}
|
|
||||||
|
|
||||||
transitionImageLayout(textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
|
||||||
copyBufferToImage(stagingBuffer, textureImage, static_cast<uint32_t>(r.w), static_cast<uint32_t>(r.h));
|
|
||||||
transitionImageLayout(textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
|
||||||
|
|
||||||
vmaDestroyBuffer(allocator, stagingBuffer, vmaAllocation);
|
vmaDestroyBuffer(allocator, stagingBuffer, vmaAllocation);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ namespace love {
|
|||||||
VkSampler getSampler() const { return textureSampler; }
|
VkSampler getSampler() const { return textureSampler; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void transitionImageLayout(VkImage, VkFormat, VkImageLayout oldLayout, VkImageLayout newLayout);
|
void transitionImageLayout(VkImage, VkImageLayout oldLayout, VkImageLayout newLayout);
|
||||||
void copyBufferToImage(VkBuffer, VkImage, uint32_t width, uint32_t height);
|
void copyBufferToImage(VkBuffer, VkImage, const Rect&);
|
||||||
void createTextureImageView();
|
void createTextureImageView();
|
||||||
void createTextureSampler();
|
void createTextureSampler();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user