mirror of
https://github.com/Yours3lf/rpi-vk-driver.git
synced 2025-02-07 04:54:20 +01:00
added mipmap generation
mipmapping reproduces infinite loop bug, to be fixed
This commit is contained in:
parent
556019790c
commit
35c3a4327a
@ -2,6 +2,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <cmath>
|
||||||
#include "driver/CustomAssert.h"
|
#include "driver/CustomAssert.h"
|
||||||
|
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
@ -613,10 +614,8 @@ VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& surfaceCapabilities)
|
|||||||
if (surfaceCapabilities.currentExtent.width == -1) {
|
if (surfaceCapabilities.currentExtent.width == -1) {
|
||||||
VkExtent2D swapChainExtent = {};
|
VkExtent2D swapChainExtent = {};
|
||||||
|
|
||||||
#define min(a, b) (a < b ? a : b)
|
swapChainExtent.width = std::min(std::max(640u, surfaceCapabilities.minImageExtent.width), surfaceCapabilities.maxImageExtent.width);
|
||||||
#define max(a, b) (a > b ? a : b)
|
swapChainExtent.height = std::min(std::max(480u, surfaceCapabilities.minImageExtent.height), surfaceCapabilities.maxImageExtent.height);
|
||||||
swapChainExtent.width = min(max(640, surfaceCapabilities.minImageExtent.width), surfaceCapabilities.maxImageExtent.width);
|
|
||||||
swapChainExtent.height = min(max(480, surfaceCapabilities.minImageExtent.height), surfaceCapabilities.maxImageExtent.height);
|
|
||||||
|
|
||||||
return swapChainExtent;
|
return swapChainExtent;
|
||||||
}
|
}
|
||||||
@ -1268,7 +1267,7 @@ void CreateTexture()
|
|||||||
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
|
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
|
||||||
uint32_t width = swapChainExtent.width, height = swapChainExtent.height;
|
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("image.ppm");
|
||||||
//char* texData = readPPM("triangle.ppm");
|
//char* texData = readPPM("triangle.ppm");
|
||||||
@ -1313,7 +1312,7 @@ void CreateTexture()
|
|||||||
imageCreateInfo.arrayLayers = 1;
|
imageCreateInfo.arrayLayers = 1;
|
||||||
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
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.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
imageCreateInfo.extent = { width, height, 1 };
|
imageCreateInfo.extent = { width, height, 1 };
|
||||||
@ -1422,6 +1421,118 @@ void CreateTexture()
|
|||||||
vkDestroyBuffer(device, stagingBuffer, 0);
|
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
|
{ //create sampler for sampling texture
|
||||||
VkImageViewCreateInfo view = {};
|
VkImageViewCreateInfo view = {};
|
||||||
@ -1433,15 +1544,15 @@ void CreateTexture()
|
|||||||
view.subresourceRange.baseMipLevel = 0;
|
view.subresourceRange.baseMipLevel = 0;
|
||||||
view.subresourceRange.baseArrayLayer = 0;
|
view.subresourceRange.baseArrayLayer = 0;
|
||||||
view.subresourceRange.layerCount = 1;
|
view.subresourceRange.layerCount = 1;
|
||||||
view.subresourceRange.levelCount = 1;
|
view.subresourceRange.levelCount = mipLevels;
|
||||||
view.image = textureImage;
|
view.image = textureImage;
|
||||||
vkCreateImageView(device, &view, nullptr, &textureView);
|
vkCreateImageView(device, &view, nullptr, &textureView);
|
||||||
|
|
||||||
VkSamplerCreateInfo sampler = {};
|
VkSamplerCreateInfo sampler = {};
|
||||||
sampler.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
sampler.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||||
sampler.magFilter = VK_FILTER_NEAREST;
|
sampler.magFilter = VK_FILTER_LINEAR;
|
||||||
sampler.minFilter = VK_FILTER_NEAREST;
|
sampler.minFilter = VK_FILTER_LINEAR;
|
||||||
sampler.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
sampler.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||||
sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
sampler.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
sampler.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
sampler.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
sampler.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user