From 85a130cefd1e5b2ef4d19e8bca78963984637816 Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Sun, 30 May 2021 17:13:16 +0200 Subject: [PATCH] [#53] Cube now textured, can't think of something funny anymore... --- config/Sources.cmake | 2 + include/vkcv/Core.hpp | 47 +++++--- include/vkcv/DescriptorConfig.hpp | 8 +- include/vkcv/DescriptorWrites.hpp | 43 +++++++ include/vkcv/Image.hpp | 3 + include/vkcv/PipelineConfig.hpp | 22 ++-- .../first_mesh/resources/shaders/frag.spv | Bin 652 -> 920 bytes .../first_mesh/resources/shaders/shader.frag | 6 +- projects/first_mesh/src/main.cpp | 48 ++++++-- projects/first_triangle/src/main.cpp | 101 ++++++++--------- src/vkcv/Core.cpp | 37 +++++- src/vkcv/DescriptorConfig.cpp | 2 +- src/vkcv/DescriptorManager.cpp | 106 +++++++++++++++++- src/vkcv/DescriptorManager.hpp | 22 +++- src/vkcv/Image.cpp | 4 + src/vkcv/PipelineConfig.cpp | 15 ++- src/vkcv/PipelineManager.cpp | 2 +- 17 files changed, 350 insertions(+), 118 deletions(-) create mode 100644 include/vkcv/DescriptorWrites.hpp diff --git a/config/Sources.cmake b/config/Sources.cmake index e7a36ff1..8fc0aa9a 100644 --- a/config/Sources.cmake +++ b/config/Sources.cmake @@ -70,4 +70,6 @@ set(vkcv_sources ${vkcv_source}/vkcv/SamplerManager.hpp ${vkcv_source}/vkcv/SamplerManager.cpp + + ${vkcv_include}/vkcv/DescriptorWrites.hpp ) diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index 6451d81a..cf75b8e7 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -20,6 +20,7 @@ #include "Result.hpp" #include "vkcv/DescriptorConfig.hpp" #include "Sampler.hpp" +#include "DescriptorWrites.hpp" namespace vkcv { @@ -64,21 +65,21 @@ namespace vkcv Context m_Context; - SwapChain m_swapchain; - std::vector<vk::ImageView> m_swapchainImageViews; - const Window& m_window; + SwapChain m_swapchain; + std::vector<vk::ImageView> m_swapchainImageViews; + const Window& m_window; - std::unique_ptr<PassManager> m_PassManager; - std::unique_ptr<PipelineManager> m_PipelineManager; - std::unique_ptr<DescriptorManager> m_DescriptorManager; - std::unique_ptr<BufferManager> m_BufferManager; - std::unique_ptr<SamplerManager> m_SamplerManager; - std::unique_ptr<ImageManager> m_ImageManager; + std::unique_ptr<PassManager> m_PassManager; + std::unique_ptr<PipelineManager> m_PipelineManager; + std::unique_ptr<DescriptorManager> m_DescriptorManager; + std::unique_ptr<BufferManager> m_BufferManager; + std::unique_ptr<SamplerManager> m_SamplerManager; + std::unique_ptr<ImageManager> m_ImageManager; - CommandResources m_CommandResources; - SyncResources m_SyncResources; - uint32_t m_currentSwapchainImageIndex; - std::vector<vk::Framebuffer> m_TemporaryFramebuffers; + CommandResources m_CommandResources; + SyncResources m_SyncResources; + uint32_t m_currentSwapchainImageIndex; + std::vector<vk::Framebuffer> m_TemporaryFramebuffers; /** * recreates the swapchain @@ -212,7 +213,10 @@ namespace vkcv * @return */ [[nodiscard]] - ResourcesHandle createResourceDescription(const std::vector<DescriptorSet> &descriptorSets); + ResourcesHandle createResourceDescription(const std::vector<DescriptorSetConfig> &descriptorSets); + void writeResourceDescription(ResourcesHandle handle, size_t setIndex, const DescriptorWrites& writes); + + vk::DescriptorSetLayout getDescritorSetLayout(ResourcesHandle handle, size_t setIndex); /** * @brief start recording command buffers and increment frame index @@ -222,9 +226,18 @@ namespace vkcv /** * @brief render a beautiful triangle */ - void renderMesh(const PassHandle renderpassHandle, const PipelineHandle pipelineHandle, - const int width, const int height, const size_t pushConstantSize, const void* pushConstantData, - const std::vector<VertexBufferBinding> & vertexBufferBindings, const BufferHandle indexBuffer, const size_t indexCount); + void renderMesh( + const PassHandle renderpassHandle, + const PipelineHandle pipelineHandle, + const int width, + const int height, + const size_t pushConstantSize, + const void* pushConstantData, + const std::vector<VertexBufferBinding> &vertexBufferBindings, + const BufferHandle indexBuffer, + const size_t indexCount, + const vkcv::ResourcesHandle resourceHandle, + const size_t resourceDescriptorSetIndex); /** * @brief end recording and present image diff --git a/include/vkcv/DescriptorConfig.hpp b/include/vkcv/DescriptorConfig.hpp index 81162597..161273db 100644 --- a/include/vkcv/DescriptorConfig.hpp +++ b/include/vkcv/DescriptorConfig.hpp @@ -11,7 +11,8 @@ namespace vkcv UNIFORM_BUFFER, STORAGE_BUFFER, SAMPLER, - IMAGE + IMAGE_SAMPLED, + IMAGE_STORAGE }; /* @@ -40,10 +41,9 @@ namespace vkcv * @param[in] a number of bindings that were created beforehand * @param[in] the number of (identical) sets that should be created from the attached bindings */ - struct DescriptorSet + struct DescriptorSetConfig { - DescriptorSet() = delete; - explicit DescriptorSet(std::vector<DescriptorBinding> bindings) noexcept; + explicit DescriptorSetConfig(std::vector<DescriptorBinding> bindings) noexcept; std::vector<DescriptorBinding> bindings; }; diff --git a/include/vkcv/DescriptorWrites.hpp b/include/vkcv/DescriptorWrites.hpp new file mode 100644 index 00000000..d67e8e32 --- /dev/null +++ b/include/vkcv/DescriptorWrites.hpp @@ -0,0 +1,43 @@ +#pragma once +#include "Handles.hpp" +#include <vector> + +namespace vkcv { + struct SampledImageDescriptorWrite { + inline SampledImageDescriptorWrite(uint32_t binding, ImageHandle image) : binding(binding), image(image) {}; + uint32_t binding; + ImageHandle image; + }; + + struct StorageImageDescriptorWrite { + inline StorageImageDescriptorWrite(uint32_t binding, ImageHandle image) : binding(binding), image(image) {}; + uint32_t binding; + ImageHandle image; + }; + + struct UniformBufferDescriptorWrite { + inline UniformBufferDescriptorWrite(uint32_t binding, BufferHandle buffer) : binding(binding), buffer(buffer) {}; + uint32_t binding; + BufferHandle buffer; + }; + + struct StorageBufferDescriptorWrite { + inline StorageBufferDescriptorWrite(uint32_t binding, BufferHandle buffer) : binding(binding), buffer(buffer) {}; + uint32_t binding; + BufferHandle buffer; + }; + + struct SamplerDescriptorWrite { + inline SamplerDescriptorWrite(uint32_t binding, SamplerHandle sampler) : binding(binding), sampler(sampler) {}; + uint32_t binding; + SamplerHandle sampler; + }; + + struct DescriptorWrites { + std::vector<SampledImageDescriptorWrite> sampledImageWrites; + std::vector<StorageImageDescriptorWrite> storageImageWrites; + std::vector<UniformBufferDescriptorWrite> uniformBufferWrites; + std::vector<StorageBufferDescriptorWrite> storageBufferWrites; + std::vector<SamplerDescriptorWrite> samplerWrites; + }; +} \ No newline at end of file diff --git a/include/vkcv/Image.hpp b/include/vkcv/Image.hpp index 5050513b..d56fac9c 100644 --- a/include/vkcv/Image.hpp +++ b/include/vkcv/Image.hpp @@ -28,6 +28,9 @@ namespace vkcv { [[nodiscard]] vk::ImageLayout getLayout() const; + + [[nodiscard]] + vkcv::ImageHandle getHandle() const; void switchLayout(vk::ImageLayout newLayout); diff --git a/include/vkcv/PipelineConfig.hpp b/include/vkcv/PipelineConfig.hpp index fdf5df74..a8e1334f 100644 --- a/include/vkcv/PipelineConfig.hpp +++ b/include/vkcv/PipelineConfig.hpp @@ -24,17 +24,19 @@ namespace vkcv { * @param passHandle handle for Render Pass */ PipelineConfig( - const ShaderProgram& shaderProgram, - uint32_t width, - uint32_t height, - PassHandle &passHandle, - const std::vector<VertexAttribute> &vertexAttributes); + const ShaderProgram& shaderProgram, + uint32_t width, + uint32_t height, + PassHandle &passHandle, + const std::vector<VertexAttribute> &vertexAttributes, + const std::vector<vk::DescriptorSetLayout> &descriptorLayouts); - ShaderProgram m_ShaderProgram; - uint32_t m_Height; - uint32_t m_Width; - PassHandle m_PassHandle; - std::vector<VertexAttribute> m_vertexAttributes; + ShaderProgram m_ShaderProgram; + uint32_t m_Height; + uint32_t m_Width; + PassHandle m_PassHandle; + std::vector<VertexAttribute> m_vertexAttributes; + std::vector<vk::DescriptorSetLayout> m_descriptorLayouts; }; } \ No newline at end of file diff --git a/projects/first_mesh/resources/shaders/frag.spv b/projects/first_mesh/resources/shaders/frag.spv index 50030afba4d1c527a1f9bc59e16cf50a50f72f94..087e4e22fb2fcec27d99b3ff2aa1a705fe755796 100644 GIT binary patch literal 920 zcmYk4UrQTN5XDF1rZHAitHzqN#Xs+%4{a%kf{N@*XrO7+$7P#b$jT<W>~2c?_54)6 z2tB_|LifTj_spC-b7ppHn-?$4Hmqs8_Rf}P-!>I7+p&7-{r<4u%Zo|x<EIZW_N-PC z;k2w_Tk_Z}jOHY^Wo_A8*(-6$sflhiRW^In!!5D=esJ^cHppEXW?|uid>T$%79_tO z+_=c$G~xJzf#1Im#%UVl#oyQkaWr?qB+A5!emi)L3NM<E<He*(@WiO<^UNzXCX3=O ziIYr{6!Gk({LJOk@9s~r$ebc|={GBuco@#o*ojR&=1apo|1ny=WmfRlB%6h?nJ*4| zcrW9CsefLg|M;we=~c~x$+KtP)028@OwV=w18tVwo|Rj+^4`|HuGp#USnv4;V7}g| zaAS2Re!0SECVwLJO?mkAtDZHc#?C4Mml|N^<aDHBPaa;YjPUO)d0^(_bk*^-JT=gH zC{JJJ;q8$;J&Dr;%r1z*e<Kf{Zw$XHPi{RIm|YS3tglC1xEyAEQpA(LQWOolGG+jy ycVC9qkyz+Fkij7i2VKW9H2o9@Jts1F#0T0mS~@b~7zaIQxt0p{PX1ZZFS38`7*62; delta 299 zcmYk1O$x#=6oe<OwOEaR72Jv7!i5(Q1YJrIL=XiRg54{MJ%M`>N;lraGk6#eAvhxy z3=GLPZ{ACC_phFHot_UE1h8nOcIH(8gz5GXo#G^!AJ2z)4|pgbWI^6)4NS=;a);6q ztMQ+e7n|&9mYV?+MN&X<O}gYV4~F6cFv?j|<h98S?&@(U<(u49ldrru%wA4^rwNu) k_l>U=S94D{E;vVCjS~NK$+LBO%Bwzx`~91|H}4x#AKFP4JOBUy diff --git a/projects/first_mesh/resources/shaders/shader.frag b/projects/first_mesh/resources/shaders/shader.frag index ce1efbde..71a1de69 100644 --- a/projects/first_mesh/resources/shaders/shader.frag +++ b/projects/first_mesh/resources/shaders/shader.frag @@ -6,7 +6,9 @@ layout(location = 1) in vec2 passUV; layout(location = 0) out vec3 outColor; +layout(set=0, binding=0) uniform texture2D meshTexture; +layout(set=0, binding=1) uniform sampler textureSampler; + void main() { - outColor = 0.5 * passNormal + 0.5; - //outColor = vec3(abs(passUV), 0); + outColor = texture(sampler2D(meshTexture, textureSampler), passUV).rgb; } \ No newline at end of file diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp index fbd32539..107cd432 100644 --- a/projects/first_mesh/src/main.cpp +++ b/projects/first_mesh/src/main.cpp @@ -5,7 +5,6 @@ #include <chrono> #include <vkcv/asset/asset_loader.hpp> - int main(int argc, const char** argv) { const char* applicationName = "First Mesh"; @@ -100,7 +99,19 @@ int main(int argc, const char** argv) { return static_cast<uint32_t>(x.type) < static_cast<uint32_t>(y.type); }); - const vkcv::PipelineConfig trianglePipelineDefinition(triangleShaderProgram, windowWidth, windowHeight, trianglePass, mesh.vertexGroups[0].vertexBuffer.attributes); + vkcv::DescriptorSetConfig setConfig({ + vkcv::DescriptorBinding(vkcv::DescriptorType::IMAGE_SAMPLED, 1, vkcv::ShaderStage::FRAGMENT), + vkcv::DescriptorBinding(vkcv::DescriptorType::SAMPLER, 1, vkcv::ShaderStage::FRAGMENT) + }); + vkcv::ResourcesHandle set = core.createResourceDescription({ setConfig }); + + const vkcv::PipelineConfig trianglePipelineDefinition( + triangleShaderProgram, + windowWidth, + windowHeight, + trianglePass, + mesh.vertexGroups[0].vertexBuffer.attributes, + { core.getDescritorSetLayout(set, 0) }); vkcv::PipelineHandle trianglePipeline = core.createGraphicsPipeline(trianglePipelineDefinition); if (!trianglePipeline) { @@ -109,15 +120,26 @@ int main(int argc, const char** argv) { } vkcv::Image texture = core.createImage(vk::Format::eR8G8B8A8Srgb, mesh.texture_hack.w, mesh.texture_hack.h); - texture.fill(mesh.texture_hack.img); + vkcv::SamplerHandle sampler = core.createSampler( + vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerMipmapMode::LINEAR, + vkcv::SamplerAddressMode::REPEAT + ); + std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = { { mesh.vertexGroups[0].vertexBuffer.attributes[0].offset, vertexBuffer.getHandle() }, { mesh.vertexGroups[0].vertexBuffer.attributes[1].offset, vertexBuffer.getHandle() }, { mesh.vertexGroups[0].vertexBuffer.attributes[2].offset, vertexBuffer.getHandle() } }; + vkcv::DescriptorWrites setWrites; + setWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(0, texture.getHandle()) }; + setWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(1, sampler) }; + core.writeResourceDescription(set, 0, setWrites); + auto start = std::chrono::system_clock::now(); while (window.isWindowOpen()) { core.beginFrame(); @@ -129,15 +151,17 @@ int main(int argc, const char** argv) { const glm::mat4 mvp = cameraManager.getCamera().getProjection() * cameraManager.getCamera().getView(); core.renderMesh( - trianglePass, - trianglePipeline, - windowWidth, - windowHeight, - sizeof(mvp), - &mvp, - vertexBufferBindings, - indexBuffer.getHandle(), - mesh.vertexGroups[0].numIndices + trianglePass, + trianglePipeline, + windowWidth, + windowHeight, + sizeof(mvp), + &mvp, + vertexBufferBindings, + indexBuffer.getHandle(), + mesh.vertexGroups[0].numIndices, + set, + 0 ); core.endFrame(); diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp index d51d60e4..2c071b72 100644 --- a/projects/first_triangle/src/main.cpp +++ b/projects/first_triangle/src/main.cpp @@ -5,41 +5,41 @@ #include <chrono> int main(int argc, const char** argv) { - const char* applicationName = "First Triangle"; + const char* applicationName = "First Triangle"; const int windowWidth = 800; const int windowHeight = 600; - vkcv::Window window = vkcv::Window::create( + vkcv::Window window = vkcv::Window::create( applicationName, windowWidth, windowHeight, false - ); + ); - vkcv::CameraManager cameraManager(window, windowWidth, windowHeight); + vkcv::CameraManager cameraManager(window, windowWidth, windowHeight); - window.initEvents(); + window.initEvents(); vkcv::Core core = vkcv::Core::create( - window, - applicationName, + window, + applicationName, VK_MAKE_VERSION(0, 0, 1), - {vk::QueueFlagBits::eTransfer,vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute}, + { vk::QueueFlagBits::eTransfer,vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute }, {}, - {"VK_KHR_swapchain"} + { "VK_KHR_swapchain" } ); - const auto &context = core.getContext(); + const auto& context = core.getContext(); const vk::Instance& instance = context.getInstance(); const vk::PhysicalDevice& physicalDevice = context.getPhysicalDevice(); const vk::Device& device = context.getDevice(); - + struct vec3 { float x, y, z; }; - + const size_t n = 5027; - + auto testBuffer = core.createBuffer<vec3>(vkcv::BufferType::VERTEX, n, vkcv::BufferMemoryType::DEVICE_LOCAL); vec3 vec_data[n]; @@ -58,26 +58,26 @@ int main(int argc, const char** argv) { m[1] = { 0, 0, 0 }; m[2] = { 0, 0, 0 }; buffer.unmap();*/ - + vkcv::SamplerHandle sampler = core.createSampler( - vkcv::SamplerFilterType::NEAREST, - vkcv::SamplerFilterType::NEAREST, - vkcv::SamplerMipmapMode::NEAREST, - vkcv::SamplerAddressMode::REPEAT + vkcv::SamplerFilterType::NEAREST, + vkcv::SamplerFilterType::NEAREST, + vkcv::SamplerMipmapMode::NEAREST, + vkcv::SamplerAddressMode::REPEAT ); std::cout << "Physical device: " << physicalDevice.getProperties().deviceName << std::endl; switch (physicalDevice.getProperties().vendorID) { - case 0x1002: std::cout << "Running AMD huh? You like underdogs, are you a Linux user?" << std::endl; break; - case 0x10DE: std::cout << "An NVidia GPU, how predictable..." << std::endl; break; - case 0x8086: std::cout << "Poor child, running on an Intel GPU, probably integrated..." - "or perhaps you are from the future with a dedicated one?" << std::endl; break; - case 0x13B5: std::cout << "ARM? What the hell are you running on, next thing I know you're trying to run Vulkan on a leg..." << std::endl; break; - default: std::cout << "Unknown GPU vendor?! Either you're on an exotic system or your driver is broken..." << std::endl; + case 0x1002: std::cout << "Running AMD huh? You like underdogs, are you a Linux user?" << std::endl; break; + case 0x10DE: std::cout << "An NVidia GPU, how predictable..." << std::endl; break; + case 0x8086: std::cout << "Poor child, running on an Intel GPU, probably integrated..." + "or perhaps you are from the future with a dedicated one?" << std::endl; break; + case 0x13B5: std::cout << "ARM? What the hell are you running on, next thing I know you're trying to run Vulkan on a leg..." << std::endl; break; + default: std::cout << "Unknown GPU vendor?! Either you're on an exotic system or your driver is broken..." << std::endl; } - // an example attachment for passes that output to the window + // an example attachment for passes that output to the window const vkcv::AttachmentDescription present_color_attachment( vkcv::AttachmentLayout::UNDEFINED, vkcv::AttachmentLayout::COLOR_ATTACHMENT, @@ -86,7 +86,7 @@ int main(int argc, const char** argv) { vkcv::AttachmentOperation::CLEAR, core.getSwapchainImageFormat()); - vkcv::PassConfig trianglePassDefinition({present_color_attachment}); + vkcv::PassConfig trianglePassDefinition({ present_color_attachment }); vkcv::PassHandle trianglePass = core.createPass(trianglePassDefinition); if (!trianglePass) @@ -99,9 +99,15 @@ int main(int argc, const char** argv) { triangleShaderProgram.addShader(vkcv::ShaderStage::VERTEX, std::filesystem::path("shaders/vert.spv")); triangleShaderProgram.addShader(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("shaders/frag.spv")); triangleShaderProgram.reflectShader(vkcv::ShaderStage::VERTEX); - triangleShaderProgram.reflectShader(vkcv::ShaderStage::FRAGMENT); + triangleShaderProgram.reflectShader(vkcv::ShaderStage::FRAGMENT); - const vkcv::PipelineConfig trianglePipelineDefinition(triangleShaderProgram, windowWidth, windowHeight, trianglePass, {}); + const vkcv::PipelineConfig trianglePipelineDefinition( + triangleShaderProgram, + windowWidth, + windowHeight, + trianglePass, + {}, + {}); vkcv::PipelineHandle trianglePipeline = core.createGraphicsPipeline(trianglePipelineDefinition); if (!trianglePipeline) @@ -110,24 +116,6 @@ int main(int argc, const char** argv) { return EXIT_FAILURE; } - //just an example - //creates 20 descriptor sets, each containing bindings for 50 uniform buffers, images, and samplers - std::vector<vkcv::DescriptorSet> sets; - - for (uint32_t i = 0; i < 20; i++) - { - vkcv::DescriptorBinding uniformBufBinding(vkcv::DescriptorType::UNIFORM_BUFFER, 50, vkcv::ShaderStage::VERTEX); - vkcv::DescriptorBinding storageBufBinding(vkcv::DescriptorType::STORAGE_BUFFER, 50, vkcv::ShaderStage::VERTEX); - vkcv::DescriptorBinding imageBinding(vkcv::DescriptorType::IMAGE, 50, vkcv::ShaderStage::VERTEX); - vkcv::DescriptorBinding samplerBinding(vkcv::DescriptorType::SAMPLER, 50, vkcv::ShaderStage::VERTEX); - - vkcv::DescriptorSet set({uniformBufBinding, storageBufBinding, imageBinding, samplerBinding}); - - sets.push_back(set); - auto resourceHandle = core.createResourceDescription(sets); - std::cout << "Resource " << resourceHandle << " created." << std::endl; - } - std::vector<vkcv::VertexBufferBinding> vertexBufferBindings; /* @@ -157,16 +145,17 @@ int main(int argc, const char** argv) { const glm::mat4 mvp = cameraManager.getCamera().getProjection() * cameraManager.getCamera().getView(); core.renderMesh( - trianglePass, - trianglePipeline, - windowWidth, - windowHeight, - sizeof(mvp), - &mvp, - vertexBufferBindings, - triangleIndexBuffer.getHandle(), - 3 - ); + trianglePass, + trianglePipeline, + windowWidth, + windowHeight, + sizeof(mvp), + &mvp, + vertexBufferBindings, + triangleIndexBuffer.getHandle(), + 3, + vkcv::ResourcesHandle(), + 0); core.endFrame(); } diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index d8a67ebd..0b0d3a24 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -173,9 +173,19 @@ namespace vkcv return device.createFramebuffer(createInfo); } - void Core::renderMesh(const PassHandle renderpassHandle, const PipelineHandle pipelineHandle, - const int width, const int height, const size_t pushConstantSize, const void *pushConstantData, - const std::vector<VertexBufferBinding>& vertexBufferBindings, const BufferHandle indexBuffer, const size_t indexCount) { + void Core::renderMesh( + const PassHandle renderpassHandle, + const PipelineHandle pipelineHandle, + const int width, + const int height, + const size_t pushConstantSize, + const void *pushConstantData, + const std::vector<VertexBufferBinding>& vertexBufferBindings, + const BufferHandle indexBuffer, + const size_t indexCount, + const vkcv::ResourcesHandle resourceHandle, + const size_t resourceDescriptorSetIndex + ) { if (m_currentSwapchainImageIndex == std::numeric_limits<uint32_t>::max()) { return; @@ -254,6 +264,11 @@ namespace vkcv cmdBuffer.bindVertexBuffers(i, (vertexBuffer), (vertexBinding.offset)); } + if (resourceHandle) { + const vk::DescriptorSet descriptorSet = m_DescriptorManager->getDescriptorSet(resourceHandle, resourceDescriptorSetIndex); + cmdBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSet, nullptr); + } + cmdBuffer.bindIndexBuffer(vulkanIndexBuffer, 0, vk::IndexType::eUint16); //FIXME: choose proper size cmdBuffer.pushConstants(pipelineLayout, vk::ShaderStageFlagBits::eAll, 0, pushConstantSize, pushConstantData); cmdBuffer.drawIndexed(indexCount, 1, 0, 0, {}); @@ -332,8 +347,22 @@ namespace vkcv return Image::create(m_ImageManager.get(), format, width, height, depth); } - ResourcesHandle Core::createResourceDescription(const std::vector<DescriptorSet> &descriptorSets) + ResourcesHandle Core::createResourceDescription(const std::vector<DescriptorSetConfig> &descriptorSets) { return m_DescriptorManager->createResourceDescription(descriptorSets); } + + void Core::writeResourceDescription(ResourcesHandle handle, size_t setIndex, const DescriptorWrites &writes) { + m_DescriptorManager->writeResourceDescription( + handle, + setIndex, + writes, + *m_ImageManager, + *m_BufferManager, + *m_SamplerManager); + } + + vk::DescriptorSetLayout Core::getDescritorSetLayout(ResourcesHandle handle, size_t setIndex) { + return m_DescriptorManager->getDescriptorSetLayout(handle, setIndex); + } } diff --git a/src/vkcv/DescriptorConfig.cpp b/src/vkcv/DescriptorConfig.cpp index f437ab68..c4f6e326 100644 --- a/src/vkcv/DescriptorConfig.cpp +++ b/src/vkcv/DescriptorConfig.cpp @@ -14,7 +14,7 @@ namespace vkcv { shaderStage{shaderStage} {}; - DescriptorSet::DescriptorSet(std::vector<DescriptorBinding> bindings) noexcept : + DescriptorSetConfig::DescriptorSetConfig(std::vector<DescriptorBinding> bindings) noexcept : bindings{std::move(bindings)} {}; } diff --git a/src/vkcv/DescriptorManager.cpp b/src/vkcv/DescriptorManager.cpp index c42db30f..5cb05f7a 100644 --- a/src/vkcv/DescriptorManager.cpp +++ b/src/vkcv/DescriptorManager.cpp @@ -40,7 +40,7 @@ namespace vkcv m_Device.destroy(m_Pool); } - ResourcesHandle DescriptorManager::createResourceDescription(const std::vector<DescriptorSet> &descriptorSets) + ResourcesHandle DescriptorManager::createResourceDescription(const std::vector<DescriptorSetConfig> &descriptorSets) { std::vector<vk::DescriptorSet> vk_sets; std::vector<vk::DescriptorSetLayout> vk_setLayouts; @@ -86,6 +86,105 @@ namespace vkcv return ResourcesHandle(m_NextResourceDescriptionID++); } + void DescriptorManager::writeResourceDescription( + ResourcesHandle handle, + size_t setIndex, + const DescriptorWrites &writes, + const ImageManager &imageManager, + const BufferManager &bufferManager, + const SamplerManager &samplerManager) { + + vk::DescriptorSet set = m_ResourceDescriptions[handle.getId()].descriptorSets[setIndex]; + + std::vector<vk::WriteDescriptorSet> vulkanWrites; + + for (const auto& write : writes.sampledImageWrites) { + vk::DescriptorImageInfo imageInfo( + nullptr, + imageManager.getVulkanImageView(write.image), + vk::ImageLayout::eShaderReadOnlyOptimal); + + vk::WriteDescriptorSet vulkanWrite( + set, + write.binding, + (uint32_t)0, + vk::DescriptorType::eSampledImage, + imageInfo); + vulkanWrites.push_back(vulkanWrite); + } + + for (const auto& write : writes.storageImageWrites) { + vk::DescriptorImageInfo imageInfo( + nullptr, + imageManager.getVulkanImageView(write.image), + vk::ImageLayout::eGeneral); + + vk::WriteDescriptorSet vulkanWrite( + set, + write.binding, + (uint32_t)0, + vk::DescriptorType::eStorageImage, + imageInfo); + vulkanWrites.push_back(vulkanWrite); + } + + for (const auto& write : writes.uniformBufferWrites) { + vk::DescriptorBufferInfo bufferInfo( + bufferManager.getBuffer(write.buffer), + (uint32_t)0, + bufferManager.getBufferSize(write.buffer)); + + vk::WriteDescriptorSet vulkanWrite( + set, + write.binding, + (uint32_t)0, + vk::DescriptorType::eUniformBuffer, + nullptr, + bufferInfo); + vulkanWrites.push_back(vulkanWrite); + } + + for (const auto& write : writes.storageBufferWrites) { + vk::DescriptorBufferInfo bufferInfo( + bufferManager.getBuffer(write.buffer), + (uint32_t)0, + bufferManager.getBufferSize(write.buffer)); + + vk::WriteDescriptorSet vulkanWrite( + set, + write.binding, + (uint32_t)0, + vk::DescriptorType::eStorageBuffer, + nullptr, + bufferInfo); + vulkanWrites.push_back(vulkanWrite); + } + + for (const auto& write : writes.samplerWrites) { + vk::DescriptorImageInfo imageInfo( + samplerManager.getVulkanSampler(write.sampler), + nullptr, + vk::ImageLayout::eGeneral); + + vk::WriteDescriptorSet vulkanWrite( + set, + write.binding, + (uint32_t)0, + vk::DescriptorType::eSampler, + imageInfo); + vulkanWrites.push_back(vulkanWrite); + } + m_Device.updateDescriptorSets(vulkanWrites, nullptr); + } + + vk::DescriptorSet DescriptorManager::getDescriptorSet(ResourcesHandle handle, size_t index) { + return m_ResourceDescriptions[handle.getId()].descriptorSets[index]; + } + + vk::DescriptorSetLayout DescriptorManager::getDescriptorSetLayout(ResourcesHandle handle, size_t index) { + return m_ResourceDescriptions[handle.getId()].descriptorSetLayouts[index]; + } + vk::DescriptorType DescriptorManager::convertDescriptorTypeFlag(DescriptorType type) { switch (type) { @@ -95,9 +194,12 @@ namespace vkcv return vk::DescriptorType::eStorageBuffer; case DescriptorType::SAMPLER: return vk::DescriptorType::eSampler; - case DescriptorType::IMAGE: + case DescriptorType::IMAGE_SAMPLED: return vk::DescriptorType::eSampledImage; + case DescriptorType::IMAGE_STORAGE: + return vk::DescriptorType::eStorageImage; default: + std::cerr << "Error: DescriptorManager::convertDescriptorTypeFlag, unknown DescriptorType" << std::endl; return vk::DescriptorType::eUniformBuffer; } } diff --git a/src/vkcv/DescriptorManager.hpp b/src/vkcv/DescriptorManager.hpp index 744f5570..937fb278 100644 --- a/src/vkcv/DescriptorManager.hpp +++ b/src/vkcv/DescriptorManager.hpp @@ -2,6 +2,11 @@ #include "vkcv/Handles.hpp" #include "vkcv/DescriptorConfig.hpp" +#include "vkcv/DescriptorWrites.hpp" + +#include "ImageManager.hpp" +#include "vkcv/BufferManager.hpp" +#include "SamplerManager.hpp" namespace vkcv { @@ -18,11 +23,22 @@ namespace vkcv * @param[in] vector of filled vkcv::DescriptorSet structs * @return index into that objects a resource handle */ - ResourcesHandle createResourceDescription(const std::vector<DescriptorSet> & descriptorSets); + ResourcesHandle createResourceDescription(const std::vector<DescriptorSetConfig> & descriptorSets); + + void writeResourceDescription( + ResourcesHandle handle, + size_t setIndex, + const DescriptorWrites& writes, + const ImageManager& imageManager, + const BufferManager& bufferManager, + const SamplerManager& samplerManager); + + vk::DescriptorSet getDescriptorSet(ResourcesHandle handle, size_t index); + vk::DescriptorSetLayout getDescriptorSetLayout(ResourcesHandle handle, size_t index); private: - vk::Device m_Device; - vk::DescriptorPool m_Pool; + vk::Device m_Device; + vk::DescriptorPool m_Pool; /** diff --git a/src/vkcv/Image.cpp b/src/vkcv/Image.cpp index c4341b4f..7104f784 100644 --- a/src/vkcv/Image.cpp +++ b/src/vkcv/Image.cpp @@ -38,6 +38,10 @@ namespace vkcv{ m_manager->switchImageLayout(m_handle, m_layout, newLayout); m_layout = newLayout; } + + vkcv::ImageHandle Image::getHandle() const { + return m_handle; + } void Image::fill(void *data, size_t size) { m_manager->fillImage(m_handle, data, size); diff --git a/src/vkcv/PipelineConfig.cpp b/src/vkcv/PipelineConfig.cpp index b5a8e98c..d3172584 100644 --- a/src/vkcv/PipelineConfig.cpp +++ b/src/vkcv/PipelineConfig.cpp @@ -9,15 +9,18 @@ namespace vkcv { PipelineConfig::PipelineConfig( - const ShaderProgram& shaderProgram, - uint32_t width, - uint32_t height, - PassHandle &passHandle, - const std::vector<VertexAttribute> &vertexAttributes): + const ShaderProgram& shaderProgram, + uint32_t width, + uint32_t height, + PassHandle &passHandle, + const std::vector<VertexAttribute> &vertexAttributes, + const std::vector<vk::DescriptorSetLayout> &descriptorLayouts) + : m_ShaderProgram(shaderProgram), m_Height(height), m_Width(width), m_PassHandle(passHandle), - m_vertexAttributes(vertexAttributes) + m_vertexAttributes(vertexAttributes), + m_descriptorLayouts(descriptorLayouts) {} } diff --git a/src/vkcv/PipelineManager.cpp b/src/vkcv/PipelineManager.cpp index ca6d44b5..1b0d665e 100644 --- a/src/vkcv/PipelineManager.cpp +++ b/src/vkcv/PipelineManager.cpp @@ -186,7 +186,7 @@ namespace vkcv // pipeline layout vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo( {}, - {}, + (config.m_descriptorLayouts), (pushConstantRange)); vk::PipelineLayout vkPipelineLayout{}; if (m_Device.createPipelineLayout(&pipelineLayoutCreateInfo, nullptr, &vkPipelineLayout) != vk::Result::eSuccess) -- GitLab