From e99169e655af8007c500fe9e1614ddc73c3e205e Mon Sep 17 00:00:00 2001 From: AliMehrabani Date: Mon, 18 Nov 2024 17:36:03 +0330 Subject: [PATCH] Bug fix and Adding Qt Window - TintMap bug fixed and compute UBO added for parameters - VulkanWIndow class added - Some GLFW lines for window resized handling commented - GLFW lines for instance creation replaced with non-GLFW lines (both android and linux) --- VkTest.pro | 7 +- VkTest.pro.user | 6 +- VulkanTutorial1.0/ComputeAndGraphics.cpp | 250 +++++++++++++++--- VulkanTutorial1.0/ComputeAndGraphics.h | 52 +++- VulkanTutorial1.0/Types.h | 10 +- VulkanTutorial1.0/VulkanWindow.cpp | 49 ++++ VulkanTutorial1.0/VulkanWindow.h | 37 +++ misc/TintMap.xml | 69 +++++ .../ComputeAndGraphics/compComp.spv | Bin 1764 -> 2500 bytes .../ComputeAndGraphics/shaderCompute.comp | 40 ++- .../ComputeAndGraphics/shaderCompute.vert | 1 - .../ComputeAndGraphics/vertComp.spv | Bin 1976 -> 1840 bytes 12 files changed, 460 insertions(+), 61 deletions(-) create mode 100644 VulkanTutorial1.0/VulkanWindow.cpp create mode 100644 VulkanTutorial1.0/VulkanWindow.h create mode 100644 misc/TintMap.xml diff --git a/VkTest.pro b/VkTest.pro index 937460b..de9dcda 100644 --- a/VkTest.pro +++ b/VkTest.pro @@ -1,4 +1,4 @@ -QT += +QT += core xml x11extras CONFIG += c++17 @@ -12,16 +12,19 @@ INCLUDEPATH += /usr/include/vulkan \ $$PWD/third_party/fmt/build LIBS += -lglfw -lvulkan -ldl -lpthread -lX11 -lXxf86vm -lXrandr -lXi \ + -L$$PWD/third_party/pugixml/build -lpugixml \ # -lSDL2main -lSDL2 -lvk-bootstrap \ # -L$$PWD/third_party/fmt/build -lfmt SOURCES += \ VulkanTutorial1.0/ComputeAndGraphics.cpp \ + VulkanTutorial1.0/VulkanWindow.cpp \ main.cpp HEADERS += \ \ VulkanTutorial1.0/ComputeAndGraphics.h \ - VulkanTutorial1.0/Types.h + VulkanTutorial1.0/Types.h \ + VulkanTutorial1.0/VulkanWindow.h DISTFILES += \ \ diff --git a/VkTest.pro.user b/VkTest.pro.user index 3d3a480..7914520 100644 --- a/VkTest.pro.user +++ b/VkTest.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -623,8 +623,8 @@ 0 - - + VkTest + VkTest Qt4ProjectManager.AndroidRunConfiguration:/home/ali-mehrabani/Qt_projects/VkTest/VkTest.pro 3768 diff --git a/VulkanTutorial1.0/ComputeAndGraphics.cpp b/VulkanTutorial1.0/ComputeAndGraphics.cpp index 9e0c3f5..15ad85f 100644 --- a/VulkanTutorial1.0/ComputeAndGraphics.cpp +++ b/VulkanTutorial1.0/ComputeAndGraphics.cpp @@ -59,15 +59,17 @@ void ComputeAndGraphics::initWindow() glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); _window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr); - glfwSetWindowUserPointer(_window, this); - glfwSetFramebufferSizeCallback(_window, framebufferResizeCallback); -} +// glfwSetWindowUserPointer(_window, this); +// glfwSetFramebufferSizeCallback(_window, framebufferResizeCallback); -void ComputeAndGraphics::framebufferResizeCallback(GLFWwindow* window, int /*width*/, int /*height*/) { - auto app = reinterpret_cast(glfwGetWindowUserPointer(window)); - app->framebufferResized = true; +// window = } +//void ComputeAndGraphics::framebufferResizeCallback(GLFWwindow* window, int /*width*/, int /*height*/) { +// auto app = reinterpret_cast(glfwGetWindowUserPointer(window)); +// app->framebufferResized = true; +//} + void ComputeAndGraphics::initVulkan() @@ -97,7 +99,9 @@ void ComputeAndGraphics::initVulkan() createVertexBuffer(); createIndexBuffer(); createShaderStorageBuffers(); + createComputeStorageBuffers(); createUniformBuffers(); + createComputeUniformBuffers(); createDescriptorPool(); createComputeDescriptorPool(); createDescriptorSets(); @@ -138,10 +142,10 @@ VkApplicationInfo ComputeAndGraphics::createInstanceAppInfo() VkApplicationInfo appInfo{}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.pApplicationName = "Vulkan App"; - appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); + appInfo.applicationVersion = VK_MAKE_VERSION(1, 3, 0); appInfo.pEngineName = "No Engine"; - appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); - appInfo.apiVersion = VK_API_VERSION_1_0; + appInfo.engineVersion = VK_MAKE_VERSION(1, 3, 0); + appInfo.apiVersion = VK_API_VERSION_1_3; return appInfo; } @@ -200,11 +204,14 @@ void ComputeAndGraphics::createInstance() std::vector ComputeAndGraphics::getRequiredExtensions() { - uint32_t glfwExtensionCount = 0; - const char** glfwExtensions; - glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); + std::vector extensions; + extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); - std::vector extensions(glfwExtensions, glfwExtensions + glfwExtensionCount); +#ifdef Q_OS_LINUX + extensions.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); +#elif Q_OS_ANDROID + extensions.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); +#endif if (enableValidationLayers) { extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); @@ -297,6 +304,7 @@ bool ComputeAndGraphics::checkDeviceExtensionSupport(VkPhysicalDevice device) { std::set requiredExtensions(deviceExtensions.begin(), deviceExtensions.end()); for (const auto& extension : availableExtensions) { +// qDebug() << extension.extensionName; requiredExtensions.erase(extension.extensionName); } @@ -371,8 +379,13 @@ void ComputeAndGraphics::createLogicalDevice() queueCreateInfos.push_back(createQueueInfo(queueFamily, 1, &queuePriority)); } - VkPhysicalDeviceFeatures deviceFeatures = createDeviceFeatures(); - VkDeviceCreateInfo createInfo = createLogicalDeviceInfo(queueCreateInfos, &deviceFeatures); + VkPhysicalDeviceFeatures deviceFeatures = createDeviceCoreFeatures(); + + VkPhysicalDeviceVulkan12Features deviceFeatures12 = createDeviceVulkan12Features(nullptr); +// VkPhysicalDevice8BitStorageFeaturesKHR device8BitStorageFeatures2Info = createDevice8BitStorageFeatures2Info(); +// VkPhysicalDeviceFeatures2 deviceCoreFeatures2 = createDeviceCoreFeatures2(&device8BitStorageFeatures2Info); + + VkDeviceCreateInfo createInfo = createLogicalDeviceInfo(queueCreateInfos, &deviceFeatures, &deviceFeatures12); if (vkCreateDevice(_physicalDevice, &createInfo, nullptr, &_device) != VK_SUCCESS) { throw std::runtime_error("failed to create logical device!"); @@ -393,7 +406,7 @@ VkDeviceQueueCreateInfo ComputeAndGraphics::createQueueInfo(uint32_t queueFamily return queueCreateInfo; } -VkPhysicalDeviceFeatures ComputeAndGraphics::createDeviceFeatures() +VkPhysicalDeviceFeatures ComputeAndGraphics::createDeviceCoreFeatures() { VkPhysicalDeviceFeatures deviceFeatures{}; deviceFeatures.samplerAnisotropy = VK_TRUE; @@ -401,8 +414,51 @@ VkPhysicalDeviceFeatures ComputeAndGraphics::createDeviceFeatures() return deviceFeatures; } +VkPhysicalDeviceVulkan12Features ComputeAndGraphics::createDeviceVulkan12Features(void* pNext) +{ + VkPhysicalDeviceVulkan12Features deviceFeatures12{}; + deviceFeatures12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; + deviceFeatures12.scalarBlockLayout = VK_TRUE; + deviceFeatures12.shaderInt8 = VK_TRUE; + deviceFeatures12.uniformAndStorageBuffer8BitAccess = VK_TRUE; +// deviceFeatures12.storageBuffer8BitAccess = VK_TRUE; +// deviceFeatures12.storagePushConstant8 = VK_TRUE; + deviceFeatures12.pNext = pNext; + + return deviceFeatures12; +} + +VkPhysicalDeviceVulkan13Features ComputeAndGraphics::createDeviceVulkan13Features(void* pNext) +{ + VkPhysicalDeviceVulkan13Features deviceFeatures13{}; + deviceFeatures13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES; + deviceFeatures13.pNext = pNext; + + return deviceFeatures13; +} + +VkPhysicalDeviceFeatures2 ComputeAndGraphics::createDeviceCoreFeatures2(VkPhysicalDevice8BitStorageFeatures* pNext) +{ + VkPhysicalDeviceFeatures2 deviceFeatures2{}; + deviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; + deviceFeatures2.pNext = pNext; + + return deviceFeatures2; +} + +VkPhysicalDevice8BitStorageFeaturesKHR ComputeAndGraphics::createDevice8BitStorageFeatures2Info() +{ + VkPhysicalDevice8BitStorageFeatures storage8BitFeatures{}; + storage8BitFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES; + storage8BitFeatures.uniformAndStorageBuffer8BitAccess = VK_TRUE; + storage8BitFeatures.storagePushConstant8 = VK_TRUE; + storage8BitFeatures.storageBuffer8BitAccess = VK_TRUE; + + return storage8BitFeatures; +} + VkDeviceCreateInfo ComputeAndGraphics::createLogicalDeviceInfo(std::vector& queueCreateInfos - , VkPhysicalDeviceFeatures* deviceFeatures) + , VkPhysicalDeviceFeatures* deviceFeatures, void* pNext) { VkDeviceCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; @@ -411,6 +467,7 @@ VkDeviceCreateInfo ComputeAndGraphics::createLogicalDeviceInfo(std::vector(deviceExtensions.size()); createInfo.ppEnabledExtensionNames = deviceExtensions.data(); @@ -655,7 +712,9 @@ void ComputeAndGraphics::createComputeDescriptorSetLayout() { VkDescriptorSetLayoutBinding computeLayoutBinding2 = createLayoutBindingInfo(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT); - std::vector bindings = {uboLayoutBinding, computeLayoutBinding1, computeLayoutBinding2}; + VkDescriptorSetLayoutBinding computeLayoutBinding3 = createLayoutBindingInfo(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT); + + std::vector bindings = {uboLayoutBinding, computeLayoutBinding1, computeLayoutBinding2, computeLayoutBinding3}; VkDescriptorSetLayoutCreateInfo layoutInfo{}; layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; layoutInfo.bindingCount = static_cast(bindings.size()); @@ -1037,7 +1096,7 @@ void ComputeAndGraphics::createTextureImage() { stbi_image_free(pixels); - createImage(texWidth, texHeight, 1, VK_SAMPLE_COUNT_1_BIT, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_LINEAR + createImage(texWidth, texHeight, 1, VK_SAMPLE_COUNT_1_BIT, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL , VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, _textureImage, _textureImageMemory); @@ -1269,9 +1328,9 @@ void ComputeAndGraphics::createTextureSampler() samplerInfo.compareEnable = VK_FALSE; samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS; samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - samplerInfo.mipLodBias = 0.0f; - samplerInfo.minLod = 0.0f; - samplerInfo.maxLod = 1.0; +// samplerInfo.mipLodBias = 0.0f; +// samplerInfo.minLod = 0.0f; +// samplerInfo.maxLod = 1.0; if (vkCreateSampler(_device, &samplerInfo, nullptr, &_textureSampler) != VK_SUCCESS) { throw std::runtime_error("failed to create texture sampler!"); @@ -1307,7 +1366,6 @@ void ComputeAndGraphics::copyVerticesToStagingBuffer(VkBuffer& stagingBuffer, Vk vkUnmapMemory(_device, stagingBufferMemory); } - void ComputeAndGraphics::createIndexBuffer() { VkDeviceSize bufferSize = sizeof(_indices[0]) * _indices.size(); @@ -1459,13 +1517,104 @@ void ComputeAndGraphics::initShaderStorageBuffers(VkBuffer& stagingBuffer, VkDev _shaderTransformedStorageBuffersMemory.resize(MAX_FRAMES_IN_FLIGHT); for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { - createBuffer(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT + createBuffer(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, _shaderRawStorageBuffers[i], _shaderRawStorageBuffersMemory[i]); copyBuffer(stagingBuffer, _shaderRawStorageBuffers[i], bufferSize); - createBuffer(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT - , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, _shaderTransformedStorageBuffers[i], _shaderTransformedStorageBuffersMemory[i]); - copyBuffer(stagingBuffer, _shaderTransformedStorageBuffers[i], bufferSize); + createBuffer(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT + | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, _shaderTransformedStorageBuffers[i], _shaderTransformedStorageBuffersMemory[i]); +// copyBuffer(stagingBuffer, _shaderTransformedStorageBuffers[i], bufferSize); + } +} + +void ComputeAndGraphics::createComputeStorageBuffers() +{ + QString filePath = "/home/ali-mehrabani/Qt_projects/VkTest/misc/TintMap.xml"; + QDomDocument doc = openTintMapXML(filePath); + + QVector tintMap = saveTintMapArrays(doc); + _tintMapSize = 11 * 256 * 3; + + VkBuffer stagingBuffer; + VkDeviceMemory stagingBufferMemory; + copyDataToStagingBuffer(stagingBuffer, stagingBufferMemory, tintMap.data(), _tintMapSize); + + initComputeStorageBuffers(stagingBuffer, _tintMapSize); + + vkDestroyBuffer(_device, stagingBuffer, nullptr); + vkFreeMemory(_device, stagingBufferMemory, nullptr); +} + +void ComputeAndGraphics::copyDataToStagingBuffer(VkBuffer& stagingBuffer, VkDeviceMemory& stagingBufferMemory, uint8_t* dataIn, VkDeviceSize dataSize) +{ + createBuffer(dataSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT + , stagingBuffer, stagingBufferMemory); + + void* data; + vkMapMemory(_device, stagingBufferMemory, 0, dataSize, 0, &data); + memcpy(data, dataIn, static_cast(dataSize)); + vkUnmapMemory(_device, stagingBufferMemory); +} + +QVector ComputeAndGraphics::saveTintMapArrays(QDomDocument doc) +{ + QDomElement root = doc.documentElement(); + + QDomNodeList entities = root.childNodes(); + + QVector data; + for (int i = 0; i < entities.count(); ++i) { + QDomNodeList fields = entities.at(i).childNodes(); + QString mappings = fields.at(1).toElement().attribute("value"); + QVector mappingsArray = extractIntArrayFromString(mappings, ";"); + data.append(mappingsArray); + } + + return data; +} + +QVector ComputeAndGraphics::extractIntArrayFromString(QString input, QString delimiter) +{ + QVector result; + + QStringList pixels = input.split(delimiter); + for (int i = 0; i < pixels.count(); ++i) { + QStringList rgb = pixels.at(i).split(","); + for (int j = 0; j < rgb.count(); ++j) { + result.append(static_cast(rgb.at(j).toUInt())); + } +// result.append(static_cast(1)); + } + + return result; +} + +QDomDocument ComputeAndGraphics::openTintMapXML(QString filePath) +{ + QFile file(filePath); + QDomDocument doc; + + if (!file.open(QIODevice::ReadOnly)) { + qDebug() << "Failed to open file:" << filePath; + } else + { + if (!doc.setContent(&file)) { + qDebug() << "Failed to parse XML file."; + } + file.close(); + } + return doc; +} + +void ComputeAndGraphics::initComputeStorageBuffers(VkBuffer& stagingBuffer, VkDeviceSize bufferSize) +{ + _computeStorageBuffers.resize(MAX_FRAMES_IN_FLIGHT); + _computeStorageBuffersMemory.resize(MAX_FRAMES_IN_FLIGHT); + + for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { + createBuffer(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT + , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, _computeStorageBuffers[i], _computeStorageBuffersMemory[i]); + copyBuffer(stagingBuffer, _computeStorageBuffers[i], bufferSize); } } @@ -1484,6 +1633,21 @@ void ComputeAndGraphics::createUniformBuffers() { } } +void ComputeAndGraphics::createComputeUniformBuffers() { + VkDeviceSize bufferSize = sizeof(ComputeParameters); + + _computeUniformBuffers.resize(MAX_FRAMES_IN_FLIGHT); + _computeUniformBuffersMemory.resize(MAX_FRAMES_IN_FLIGHT); + _computeUniformBuffersMapped.resize(MAX_FRAMES_IN_FLIGHT); + + for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { + createBuffer(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT + , _computeUniformBuffers[i], _computeUniformBuffersMemory[i]); + + vkMapMemory(_device, _computeUniformBuffersMemory[i], 0, bufferSize, 0, &_computeUniformBuffersMapped[i]); + } +} + void ComputeAndGraphics::createDescriptorPool() { std::array poolSizes{}; poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; @@ -1507,7 +1671,7 @@ void ComputeAndGraphics::createComputeDescriptorPool() { poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; poolSizes[0].descriptorCount = static_cast(MAX_FRAMES_IN_FLIGHT); poolSizes[1].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - poolSizes[1].descriptorCount = static_cast(MAX_FRAMES_IN_FLIGHT) * 2; + poolSizes[1].descriptorCount = static_cast(MAX_FRAMES_IN_FLIGHT) * 3; VkDescriptorPoolCreateInfo poolInfo{}; poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; @@ -1603,9 +1767,9 @@ void ComputeAndGraphics::createComputeDescriptorSets() allocateComputeDescriptorSets(); for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { - VkDescriptorBufferInfo bufferInfo = createDescriptorBufferInfo(_uniformBuffers[i], sizeof(UniformBufferObject)); + VkDescriptorBufferInfo bufferInfo = createDescriptorBufferInfo(_computeUniformBuffers[i], sizeof(ComputeParameters)); - std::array descriptorWrites{}; + std::array descriptorWrites{}; addUniformBufferWriteDescriptor(descriptorWrites[0], &bufferInfo, _computeDescriptorSets[i], 0); @@ -1615,6 +1779,9 @@ void ComputeAndGraphics::createComputeDescriptorSets() VkDescriptorBufferInfo storageBufferInfoCurrentFrame = createDescriptorBufferInfo(_shaderTransformedStorageBuffers[i], _textureImageSize); addStorageBufferWriteDescriptor(descriptorWrites[2], &storageBufferInfoCurrentFrame, _computeDescriptorSets[i], 2); + VkDescriptorBufferInfo computeBufferInfo = createDescriptorBufferInfo(_computeStorageBuffers[i], _tintMapSize); + addStorageBufferWriteDescriptor(descriptorWrites[3], &computeBufferInfo, _computeDescriptorSets[i], 3); + vkUpdateDescriptorSets(_device, static_cast(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr); } } @@ -1740,6 +1907,8 @@ void ComputeAndGraphics::computeSubmission() { vkWaitForFences(_device, 1, &_computeInFlightFences[currentFrame], VK_TRUE, UINT64_MAX); + updateComputeUniformBuffer(currentFrame); + vkResetFences(_device, 1, &_computeInFlightFences[currentFrame]); vkResetCommandBuffer(_computeCommandBuffers[currentFrame], /*VkCommandBufferResetFlagBits*/ 0); @@ -1948,7 +2117,9 @@ void ComputeAndGraphics::recordComputeCommandBuffer(VkCommandBuffer commandBuffe vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, _computePipelineLayout, 0, 1, &_computeDescriptorSets[currentFrame], 0, nullptr); - vkCmdDispatch(commandBuffer, static_cast(_textureImageSize / 8), 1, 1); + vkCmdDispatch(commandBuffer, static_cast((_textureImageSize) / 256) + , 1 + , 1); if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS) { throw std::runtime_error("failed to record compute command buffer!"); @@ -1964,13 +2135,21 @@ void ComputeAndGraphics::updateUniformBuffer(uint32_t currentImage) { UniformBufferObject ubo{}; ubo.model = glm::rotate(glm::mat4(1.0f), glm::radians(0.0f), glm::vec3(0.0f, 0.0f, 1.0f)); - ubo.view = glm::lookAt(glm::vec3(0.001f, 0.001f, 1.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)); + ubo.view = glm::lookAt(glm::vec3(0.0f, 0.00001f, 1.5f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)); ubo.proj = glm::perspective(glm::radians(45.0f), _swapChainExtent.width / static_cast(_swapChainExtent.height), 0.1f, 10.0f); ubo.proj[1][1] *= -1; memcpy(_uniformBuffersMapped[currentImage], &ubo, sizeof(ubo)); } +void ComputeAndGraphics::updateComputeUniformBuffer(uint32_t currentImage) +{ + ComputeParameters ubo{}; + ubo.tintMapType = 4; + + memcpy(_computeUniformBuffersMapped[currentImage], &ubo, sizeof(ubo)); +} + void ComputeAndGraphics::recreateSwapChain() { int width = 0, height = 0; glfwGetFramebufferSize(_window, &width, &height); @@ -2022,13 +2201,20 @@ void ComputeAndGraphics::cleanBuffers() for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { vkDestroyBuffer(_device, _shaderRawStorageBuffers[i], nullptr); vkFreeMemory(_device, _shaderRawStorageBuffersMemory[i], nullptr); + vkDestroyBuffer(_device, _shaderTransformedStorageBuffers[i], nullptr); vkFreeMemory(_device, _shaderTransformedStorageBuffersMemory[i], nullptr); + + vkDestroyBuffer(_device, _computeStorageBuffers[i], nullptr); + vkFreeMemory(_device, _computeStorageBuffersMemory[i], nullptr); } for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { vkDestroyBuffer(_device, _uniformBuffers[i], nullptr); vkFreeMemory(_device, _uniformBuffersMemory[i], nullptr); + + vkDestroyBuffer(_device, _computeUniformBuffers[i], nullptr); + vkFreeMemory(_device, _computeUniformBuffersMemory[i], nullptr); } vkDestroyBuffer(_device, _indexBuffer, nullptr); diff --git a/VulkanTutorial1.0/ComputeAndGraphics.h b/VulkanTutorial1.0/ComputeAndGraphics.h index 434877e..eb4cbda 100644 --- a/VulkanTutorial1.0/ComputeAndGraphics.h +++ b/VulkanTutorial1.0/ComputeAndGraphics.h @@ -10,10 +10,9 @@ #endif #include "Types.h" +#include "VulkanWindow.h" #include - - #include #include // Necessary for uint32_t #include // Necessary for std::numeric_limits @@ -21,11 +20,9 @@ #include #include -#ifdef Q_OS_ANDROID - const QString TARGET_PLATFORM = "Android"; -#else - const QString TARGET_PLATFORM = "Linux"; -#endif +#include +#include +#include const int MAX_FRAMES_IN_FLIGHT = 2; @@ -38,6 +35,10 @@ struct QueueFamilyIndices { } }; +struct ComputeParameters { + alignas(16) glm::uint32 tintMapType; +}; + struct Vertex { alignas(16) glm::vec3 pos; alignas(16) glm::vec3 color; @@ -100,7 +101,7 @@ public: } static std::vector readFile(const std::string& filename); - static void framebufferResizeCallback(GLFWwindow* window, int width, int height); +// static void framebufferResizeCallback(GLFWwindow* window, int width, int height); // static void framebufferResizeCallback(QQuickWindow* window, int width, int height); private: @@ -186,14 +187,25 @@ private: void createComputeDescriptorSetLayout(); void createComputeDescriptorPool(); + void createComputeStorageBuffers(); + void initComputeStorageBuffers(VkBuffer& stagingBuffer, VkDeviceSize bufferSize); + + void createComputeUniformBuffers(); + void updateComputeUniformBuffer(uint32_t currentImage); + VkApplicationInfo createInstanceAppInfo(); VkDebugUtilsMessengerCreateInfoEXT createInstanceDebugMessengerInfo(); VkInstanceCreateInfo createInstanceInfo(VkApplicationInfo* appInfo, std::vector& extensions , VkDebugUtilsMessengerCreateInfoEXT& debugCreateInfo); VkDeviceQueueCreateInfo createQueueInfo(uint32_t queueFamily, uint32_t queueCount, float* queuePriority); - VkPhysicalDeviceFeatures createDeviceFeatures(); - VkDeviceCreateInfo createLogicalDeviceInfo(std::vector& queueCreateInfos, VkPhysicalDeviceFeatures* deviceFeatures); + VkPhysicalDeviceFeatures createDeviceCoreFeatures(); + VkPhysicalDeviceVulkan12Features createDeviceVulkan12Features(void* pNext); + VkPhysicalDeviceVulkan13Features createDeviceVulkan13Features(void* pNext); + VkPhysicalDeviceFeatures2KHR createDeviceCoreFeatures2(VkPhysicalDevice8BitStorageFeaturesKHR* pNext); + VkPhysicalDevice8BitStorageFeaturesKHR createDevice8BitStorageFeatures2Info(); + VkDeviceCreateInfo createLogicalDeviceInfo(std::vector& queueCreateInfos, VkPhysicalDeviceFeatures* deviceFeatures + , void* pNext); VkSwapchainCreateInfoKHR createSwapChainInfo(SwapChainSupportDetails swapChainSupport, VkSurfaceKHR _surface, uint32_t imageCount , VkSurfaceFormatKHR surfaceFormat, VkExtent2D extent, VkPresentModeKHR presentMode); @@ -268,6 +280,11 @@ private: void copyTransformedBufferToTextureImage(); + QDomDocument openTintMapXML(QString filePath); + QVector saveTintMapArrays(QDomDocument doc); + QVector extractIntArrayFromString(QString input, QString delimiter); + void copyDataToStagingBuffer(VkBuffer& stagingBuffer, VkDeviceMemory& stagingBufferMemory, uint8_t* dataIn, VkDeviceSize dataSize); + const int32_t WIDTH = 800; const int32_t HEIGHT = 600; @@ -275,7 +292,9 @@ private: "VK_LAYER_KHRONOS_validation" }; const std::vector deviceExtensions = { - VK_KHR_SWAPCHAIN_EXTENSION_NAME + VK_KHR_SWAPCHAIN_EXTENSION_NAME, +// VK_KHR_8BIT_STORAGE_EXTENSION_NAME, +// VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME }; const std::vector _vertices = { {{-0.5f, -0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f}}, @@ -297,7 +316,7 @@ private: bool framebufferResized = false; GLFWwindow *_window; -// QQuickWindow* _window; +// VulkanWindow _window; VkInstance _instance; VkDebugUtilsMessengerEXT _debugMessenger; VkPhysicalDevice _physicalDevice; @@ -361,6 +380,15 @@ private: std::vector _computeInFlightFences; std::vector _computeFinishedSemaphores; + std::vector _computeStorageBuffers; + std::vector _computeStorageBuffersMemory; +// uint8_t* _tintMapArray; + VkDeviceSize _tintMapSize; + + std::vector _computeUniformBuffers; + std::vector _computeUniformBuffersMemory; + std::vector _computeUniformBuffersMapped; + }; #endif // COMPUTEANDGRAPHICS_H diff --git a/VulkanTutorial1.0/Types.h b/VulkanTutorial1.0/Types.h index 5e28240..d7578be 100644 --- a/VulkanTutorial1.0/Types.h +++ b/VulkanTutorial1.0/Types.h @@ -8,10 +8,10 @@ #pragma once -#define VK_USE_PLATFORM_ +//#define VK_USE_PLATFORM_ #define GLFW_INCLUDE_VULKAN #include -#define GLFW_EXPOSE_NATIVE_ +//#define GLFW_EXPOSE_NATIVE_ #include #define GLM_FORCE_RADIANS @@ -25,6 +25,12 @@ #include +#ifdef Q_OS_ANDROID + const QString TARGET_PLATFORM = "Android"; +#else + const QString TARGET_PLATFORM = "Linux"; +#endif + struct SwapChainSupportDetails { VkSurfaceCapabilitiesKHR capabilities; std::vector formats; diff --git a/VulkanTutorial1.0/VulkanWindow.cpp b/VulkanTutorial1.0/VulkanWindow.cpp new file mode 100644 index 0000000..7547bfd --- /dev/null +++ b/VulkanTutorial1.0/VulkanWindow.cpp @@ -0,0 +1,49 @@ +#include "VulkanWindow.h" + +VulkanWindow::VulkanWindow() +{ +// setSurfaceType(QWindow::VulkanSurface); +// if (!initVulkanInstance()) { +// qCritical() << "Failed to initialize Vulkan instance!"; +// exit(EXIT_FAILURE); +// } + createVulkanSurface(); +} + +VulkanWindow::~VulkanWindow() { +// cleanup(); +} + +void VulkanWindow::createVulkanSurface() { + VkSurfaceKHR surface; + +#ifdef Q_OS_LINUX + VkXcbSurfaceCreateInfoKHR surfaceCreateInfo = {}; + surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; + surfaceCreateInfo.connection = QX11Info::connection(); + surfaceCreateInfo.window = static_cast(winId()); + + if (vkCreateXcbSurfaceKHR(_instance, &surfaceCreateInfo, nullptr, &surface) != VK_SUCCESS) { + qCritical() << "Failed to create Vulkan surface on Linux."; + exit(EXIT_FAILURE); + } +#elif Q_OS_ANDROID + VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo = {}; + surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; + surfaceCreateInfo.window = reinterpret_cast(winId()); + + if (vkCreateAndroidSurfaceKHR(_instance, &surfaceCreateInfo, nullptr, &surface) != VK_SUCCESS) { + qCritical() << "Failed to create Vulkan surface on Android."; + exit(EXIT_FAILURE); + } +#endif + _surface = surface; + qDebug() << "Vulkan surface created successfully."; + +} + +void VulkanWindow::cleanup() { + if (_surface != VK_NULL_HANDLE) { + vkDestroySurfaceKHR(_instance, _surface, nullptr); + } +} diff --git a/VulkanTutorial1.0/VulkanWindow.h b/VulkanTutorial1.0/VulkanWindow.h new file mode 100644 index 0000000..308395d --- /dev/null +++ b/VulkanTutorial1.0/VulkanWindow.h @@ -0,0 +1,37 @@ +#ifndef VULKANWINDOW_H +#define VULKANWINDOW_H + +#include +#include +#include +#include + +#include "Types.h" + +#ifdef Q_OS_ANDROID +#include +#else +#include +#endif + + +#define VK_USE_PLATFORM_XCB_KHR // Enable Vulkan support for Linux (XCB) +#define VK_USE_PLATFORM_ANDROID_KHR // Enable Vulkan support for Android + +class VulkanWindow : public QWindow +{ + Q_OBJECT + +public: + VulkanWindow(); + virtual ~VulkanWindow(); + +private: + void createVulkanSurface(); + void cleanup(); + + VkSurfaceKHR _surface; + VkInstance _instance; +}; + +#endif // VULKANWINDOW_H diff --git a/misc/TintMap.xml b/misc/TintMap.xml new file mode 100644 index 0000000..64e4e6d --- /dev/null +++ b/misc/TintMap.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/shaders/VulkanTutorial1.0/ComputeAndGraphics/compComp.spv b/shaders/VulkanTutorial1.0/ComputeAndGraphics/compComp.spv index 848ba5b4cf3e96da3f4f1ca97c2137773174e983..761540a9f7d61fa459a752c4dcd02999ee084f58 100644 GIT binary patch literal 2500 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 E2cEc$xc~qF