1
0
mirror of https://github.com/Yours3lf/rpi-vk-driver.git synced 2025-01-30 22:52:14 +01:00

added mipmap generation

mipmapping reproduces infinite loop bug, to be fixed
This commit is contained in:
Unknown 2020-02-28 20:17:34 +00:00
parent 556019790c
commit 35c3a4327a

View File

@ -2,6 +2,7 @@
#include <vector>
#include <algorithm>
#include <string.h>
#include <cmath>
#include "driver/CustomAssert.h"
#include <vulkan/vulkan.h>
@ -613,10 +614,8 @@ VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& surfaceCapabilities)
if (surfaceCapabilities.currentExtent.width == -1) {
VkExtent2D swapChainExtent = {};
#define min(a, b) (a < b ? a : b)
#define max(a, b) (a > b ? a : b)
swapChainExtent.width = min(max(640, surfaceCapabilities.minImageExtent.width), surfaceCapabilities.maxImageExtent.width);
swapChainExtent.height = min(max(480, surfaceCapabilities.minImageExtent.height), surfaceCapabilities.maxImageExtent.height);
swapChainExtent.width = std::min(std::max(640u, surfaceCapabilities.minImageExtent.width), surfaceCapabilities.maxImageExtent.width);
swapChainExtent.height = std::min(std::max(480u, surfaceCapabilities.minImageExtent.height), surfaceCapabilities.maxImageExtent.height);
return swapChainExtent;
}
@ -1268,7 +1267,7 @@ void CreateTexture()
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
uint32_t width = swapChainExtent.width, height = swapChainExtent.height;
uint32_t mipLevels = 1;
uint32_t mipLevels = std::floor(std::log2(std::max(width, height))) + 1;
char* texData = readPPM("image.ppm");
//char* texData = readPPM("triangle.ppm");
@ -1313,7 +1312,7 @@ void CreateTexture()
imageCreateInfo.arrayLayers = 1;
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
imageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageCreateInfo.extent = { width, height, 1 };
@ -1422,6 +1421,118 @@ void CreateTexture()
vkDestroyBuffer(device, stagingBuffer, 0);
}
{ // generate mipchain
VkCommandBufferAllocateInfo allocInfo = {};
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocInfo.commandPool = commandPool;
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocInfo.commandBufferCount = 1;
VkCommandBuffer mipgenCommandBuffer;
vkAllocateCommandBuffers(device, &allocInfo, &mipgenCommandBuffer);
for(uint32_t c = 1; c < mipLevels; ++c)
{
VkImageBlit imageBlit = {};
imageBlit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageBlit.srcSubresource.mipLevel = c - 1;
imageBlit.srcSubresource.layerCount = 1;
imageBlit.srcOffsets[1].x = uint32_t(width >> (c - 1));
imageBlit.srcOffsets[1].y = uint32_t(height >> (c - 1));
imageBlit.srcOffsets[1].z = 1;
imageBlit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageBlit.dstSubresource.mipLevel = c;
imageBlit.dstSubresource.layerCount = 1;
imageBlit.dstOffsets[1].x = uint32_t(width >> c);
imageBlit.dstOffsets[1].y = uint32_t(height >> c);
imageBlit.dstOffsets[1].z = 1;
VkImageSubresourceRange mipSubRange = {};
mipSubRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
mipSubRange.baseMipLevel = c;
mipSubRange.levelCount = 1;
mipSubRange.layerCount = 1;
VkImageMemoryBarrier imageMemoryBarrier = {};
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
imageMemoryBarrier.srcAccessMask = 0;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
imageMemoryBarrier.image = textureImage;
imageMemoryBarrier.subresourceRange = mipSubRange;
VkCommandBufferBeginInfo beginInfo = {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
vkBeginCommandBuffer(mipgenCommandBuffer, &beginInfo);
vkCmdPipelineBarrier(mipgenCommandBuffer,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier);
vkCmdBlitImage(mipgenCommandBuffer, textureImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, textureImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageBlit, VK_FILTER_LINEAR);
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
vkCmdPipelineBarrier(mipgenCommandBuffer,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier);
}
VkImageSubresourceRange subresourceRange = {};
subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
subresourceRange.levelCount = 1;
subresourceRange.layerCount = 1;
VkImageMemoryBarrier imageMemoryBarrier = {};
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
imageMemoryBarrier.image = textureImage;
imageMemoryBarrier.subresourceRange = subresourceRange;
vkCmdPipelineBarrier(mipgenCommandBuffer,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier);
vkEndCommandBuffer(mipgenCommandBuffer);
VkFenceCreateInfo fenceInfo = {};
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceInfo.flags = 0;
VkFence fence;
vkCreateFence(device, &fenceInfo, 0, &fence);
VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &mipgenCommandBuffer;
vkQueueSubmit(graphicsQueue, 1, &submitInfo, fence);
vkWaitForFences(device, 1, &fence, VK_TRUE, -1);
vkDestroyFence(device, fence, 0);
vkFreeCommandBuffers(device, commandPool, 1, &mipgenCommandBuffer);
vkFreeMemory(device, stagingMemory, 0);
vkDestroyBuffer(device, stagingBuffer, 0);
}
{ //create sampler for sampling texture
VkImageViewCreateInfo view = {};
@ -1433,15 +1544,15 @@ void CreateTexture()
view.subresourceRange.baseMipLevel = 0;
view.subresourceRange.baseArrayLayer = 0;
view.subresourceRange.layerCount = 1;
view.subresourceRange.levelCount = 1;
view.subresourceRange.levelCount = mipLevels;
view.image = textureImage;
vkCreateImageView(device, &view, nullptr, &textureView);
VkSamplerCreateInfo sampler = {};
sampler.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
sampler.magFilter = VK_FILTER_NEAREST;
sampler.minFilter = VK_FILTER_NEAREST;
sampler.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
sampler.magFilter = VK_FILTER_LINEAR;
sampler.minFilter = VK_FILTER_LINEAR;
sampler.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
sampler.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
sampler.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;