From 4d5ec8ef3d6767a905ca9cc3ca9be7e56a204abb Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Tue, 6 Jul 2021 15:34:43 +0200 Subject: [PATCH] [#87] Prepare mesh shader data --- .../mesh_shader/resources/shaders/shader.frag | 8 +- .../mesh_shader/resources/shaders/shader.mesh | 24 +++- .../mesh_shader/resources/shaders/shader.task | 11 -- .../mesh_shader/resources/shaders/shader.vert | 8 +- projects/mesh_shader/src/main.cpp | 127 ++++++++++++------ src/vkcv/PipelineManager.cpp | 39 +++--- 6 files changed, 135 insertions(+), 82 deletions(-) diff --git a/projects/mesh_shader/resources/shaders/shader.frag b/projects/mesh_shader/resources/shaders/shader.frag index 11d4f36e..c3740e2c 100644 --- a/projects/mesh_shader/resources/shaders/shader.frag +++ b/projects/mesh_shader/resources/shaders/shader.frag @@ -1,11 +1,9 @@ #version 450 #extension GL_ARB_separate_shader_objects : enable -layout(location = 0) in vec3 VertexColor; -layout(location = 1) in vec3 passNormal; -layout(location = 0) out vec4 outColor; +layout(location = 0) in vec3 passNormal; +layout(location = 0) out vec3 outColor; void main() { - vec3 vis = normalize(passNormal) * 0.5 +0.5; - outColor = vec4(vis , 1); + outColor = normalize(passNormal) * 0.5 +0.5; } \ No newline at end of file diff --git a/projects/mesh_shader/resources/shaders/shader.mesh b/projects/mesh_shader/resources/shaders/shader.mesh index 7e78cced..fc1480bc 100644 --- a/projects/mesh_shader/resources/shaders/shader.mesh +++ b/projects/mesh_shader/resources/shaders/shader.mesh @@ -11,7 +11,23 @@ layout( push_constant ) uniform constants{ mat4 mvp; }; -layout(location = 0) out vec3 vertexColors[]; +layout(location = 0) out vec3 passNormal[]; + +struct Vertex +{ + vec3 position; + vec3 normal; +}; + +layout(std430, binding = 0) readonly buffer vertexBuffer +{ + Vertex vertices[]; +}; + +layout(std430, binding = 1) readonly buffer indexBuffer +{ + uint indices[]; // breaks for 16 bit indices +}; void main() { if(gl_LocalInvocationID.x == 0) @@ -25,8 +41,8 @@ void main() { gl_MeshVerticesNV[1].gl_Position = mvp * vec4( 0.5, 0.5, 0.5, 1); gl_MeshVerticesNV[2].gl_Position = mvp * vec4( 0 , -0.5, 0.5, 1); - vertexColors[0] = vec3(1, 0, 0); - vertexColors[1] = vec3(0, 1, 0); - vertexColors[2] = vec3(0, 0, 1); + passNormal[0] = vec3(1, 0, 0); + passNormal[1] = vec3(0, 1, 0); + passNormal[2] = vec3(0, 0, 1); } } \ No newline at end of file diff --git a/projects/mesh_shader/resources/shaders/shader.task b/projects/mesh_shader/resources/shaders/shader.task index 1b2472df..a41b6d21 100644 --- a/projects/mesh_shader/resources/shaders/shader.task +++ b/projects/mesh_shader/resources/shaders/shader.task @@ -9,17 +9,6 @@ layout(local_size_x=32) in; // uint subIDs[32]; //} OUT; -struct Mesh -{ - vec3 position; - vec3 index; -}; - -layout(std430, binding = 0) coherent buffer buffer_inMesh -{ - Mesh mesh[]; -}; - void main() { if(gl_LocalInvocationID.x == 0) { diff --git a/projects/mesh_shader/resources/shaders/shader.vert b/projects/mesh_shader/resources/shaders/shader.vert index 425fc412..5e1f72dc 100644 --- a/projects/mesh_shader/resources/shaders/shader.vert +++ b/projects/mesh_shader/resources/shaders/shader.vert @@ -4,15 +4,13 @@ layout(location = 0) in vec3 inPosition; layout(location = 1) in vec3 inNormal; -layout(location = 0) out vec3 fragColor; -layout(location = 1) out vec3 passNormal; +layout(location = 0) out vec3 passNormal; layout( push_constant ) uniform constants{ mat4 mvp; }; void main() { - gl_Position = mvp * vec4(inPosition, 1.0); - passNormal = inNormal; - fragColor = vec3(1.f); + gl_Position = mvp * vec4(inPosition, 1.0); + passNormal = inNormal; } \ No newline at end of file diff --git a/projects/mesh_shader/src/main.cpp b/projects/mesh_shader/src/main.cpp index 884581ef..03e4b68e 100644 --- a/projects/mesh_shader/src/main.cpp +++ b/projects/mesh_shader/src/main.cpp @@ -9,6 +9,40 @@ #include <vkcv/asset/asset_loader.hpp> #include "MeshStruct.hpp" +struct Vertex { + glm::vec3 position; + glm::vec3 normal; +}; + +std::vector<Vertex> convertToVertices( + const std::vector<uint8_t>& vertexData, + const uint64_t vertexCount, + const vkcv::asset::VertexAttribute& positionAttribute, + const vkcv::asset::VertexAttribute& normalAttribute) { + + assert(positionAttribute.type == vkcv::asset::PrimitiveType::POSITION); + assert(normalAttribute.type == vkcv::asset::PrimitiveType::NORMAL); + + std::vector<Vertex> vertices; + vertices.reserve(vertexCount); + + const size_t positionStepSize = positionAttribute.stride == 0 ? sizeof(glm::vec3) : positionAttribute.stride; + const size_t normalStepSize = normalAttribute.stride == 0 ? sizeof(glm::vec3) : normalAttribute.stride; + + for (int i = 0; i < vertexCount; i++) { + Vertex v; + + const size_t positionOffset = positionAttribute.offset + positionStepSize * i; + const size_t normalOffset = normalAttribute.offset + normalStepSize * i; + + v.position = *reinterpret_cast<const glm::vec3*>(&(vertexData[positionOffset])); + v.normal = *reinterpret_cast<const glm::vec3*>(&(vertexData[normalOffset])); + vertices.push_back(v); + } + + return vertices; +} + int main(int argc, const char** argv) { const char* applicationName = "Mesh shader"; @@ -57,18 +91,33 @@ int main(int argc, const char** argv) { ); indexBuffer.fill(mesh.vertexGroups[0].indexBuffer.data); - auto meshBuffer = core.createBuffer<MeshStruct>( - vkcv::BufferType::STORAGE, - mesh.vertexGroups[0].vertexBuffer.data.size() - ); -// meshBuffer.fill(); + // format data for mesh shader + auto& attributes = mesh.vertexGroups[0].vertexBuffer.attributes; - auto& attributes = mesh.vertexGroups[0].vertexBuffer.attributes; + std::sort(attributes.begin(), attributes.end(), [](const vkcv::asset::VertexAttribute& x, const vkcv::asset::VertexAttribute& y) { + return static_cast<uint32_t>(x.type) < static_cast<uint32_t>(y.type); + }); + + const std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = { + vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[0].offset), vertexBuffer.getVulkanHandle()), + vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[1].offset), vertexBuffer.getVulkanHandle()), + vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[2].offset), vertexBuffer.getVulkanHandle()) }; + + const auto& bunny = mesh.vertexGroups[0]; + const auto interleavedVertices = convertToVertices(bunny.vertexBuffer.data, bunny.numVertices, attributes[0], attributes[1]); - std::sort(attributes.begin(), attributes.end(), [](const vkcv::asset::VertexAttribute& x, const vkcv::asset::VertexAttribute& y) { - return static_cast<uint32_t>(x.type) < static_cast<uint32_t>(y.type); - }); + // mesh shader buffers + auto meshBuffer = core.createBuffer<Vertex>( + vkcv::BufferType::STORAGE, + interleavedVertices.size()); + meshBuffer.fill(interleavedVertices); + auto meshShaderIndexBuffer = core.createBuffer<uint8_t>( + vkcv::BufferType::STORAGE, + mesh.vertexGroups[0].indexBuffer.data.size()); + meshShaderIndexBuffer.fill(mesh.vertexGroups[0].indexBuffer.data); + + // attachments const vkcv::AttachmentDescription present_color_attachment( vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::CLEAR, @@ -145,7 +194,7 @@ int main(int argc, const char** argv) { }); uint32_t setID = 0; - vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet( meshShaderProgram.getReflectedDescriptors()[setID]); + vkcv::DescriptorSetHandle meshShaderDescriptorSet = core.createDescriptorSet( meshShaderProgram.getReflectedDescriptors()[setID]); const vkcv::VertexLayout meshShaderLayout(bindings); const vkcv::PipelineConfig meshShaderPipelineDefinition{ @@ -154,7 +203,7 @@ int main(int argc, const char** argv) { (uint32_t)windowHeight, renderPass, {meshShaderLayout}, - {core.getDescriptorSet(descriptorSet).layout}, + {core.getDescriptorSet(meshShaderDescriptorSet).layout}, false }; @@ -166,14 +215,11 @@ int main(int argc, const char** argv) { return EXIT_FAILURE; } - const std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = { - vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[0].offset), vertexBuffer.getVulkanHandle()), - vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[1].offset), vertexBuffer.getVulkanHandle()), - vkcv::VertexBufferBinding(static_cast<vk::DeviceSize>(attributes[2].offset), vertexBuffer.getVulkanHandle()) }; - - vkcv::DescriptorWrites setWrites; - setWrites.storageBufferWrites = {vkcv::StorageBufferDescriptorWrite(0, meshBuffer.getHandle())}; - core.writeDescriptorSet( descriptorSet, setWrites); + vkcv::DescriptorWrites meshShaderWrites; + meshShaderWrites.storageBufferWrites = { + vkcv::StorageBufferDescriptorWrite(0, meshBuffer.getHandle()), + vkcv::StorageBufferDescriptorWrite(1, meshShaderIndexBuffer.getHandle()) }; + core.writeDescriptorSet( meshShaderDescriptorSet, meshShaderWrites); vkcv::ImageHandle depthBuffer = core.createImage(vk::Format::eD32Sfloat, windowWidth, windowHeight, 1, false).getHandle(); @@ -183,9 +229,6 @@ int main(int argc, const char** argv) { const vkcv::Mesh renderMesh(vertexBufferBindings, indexBuffer.getVulkanHandle(), mesh.vertexGroups[0].numIndices, vkcv::IndexBitCount::Bit32); -// vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(descriptorSet).vulkanHandle); - vkcv::DrawcallInfo drawcall(renderMesh, {}); - const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); vkcv::camera::CameraManager cameraManager(window); @@ -216,23 +259,29 @@ int main(int argc, const char** argv) { const std::vector<vkcv::ImageHandle> renderTargets = { swapchainInput, depthBuffer }; auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - /* - core.recordMeshShaderDrawcalls( - cmdStream, - renderPass, - meshShaderPipeline, - pushConstantData, - { vkcv::MeshShaderDrawcall({}, 1) }, - { swapchainInput }); - */ - - core.recordDrawcallsToCmdStream( - cmdStream, - renderPass, - bunnyPipeline, - pushConstantData, - { drawcall }, - { renderTargets }); + const bool useMeshShader = true; + + if (useMeshShader) { + + vkcv::DescriptorSetUsage descriptorUsage(0, core.getDescriptorSet(meshShaderDescriptorSet).vulkanHandle); + + core.recordMeshShaderDrawcalls( + cmdStream, + renderPass, + meshShaderPipeline, + pushConstantData, + { vkcv::MeshShaderDrawcall({descriptorUsage}, 1) }, + { renderTargets }); + } + else { + core.recordDrawcallsToCmdStream( + cmdStream, + renderPass, + bunnyPipeline, + pushConstantData, + { vkcv::DrawcallInfo(renderMesh, {}) }, + { renderTargets }); + } core.prepareSwapchainImageForPresent(cmdStream); core.submitCommandStream(cmdStream); diff --git a/src/vkcv/PipelineManager.cpp b/src/vkcv/PipelineManager.cpp index fc77e37d..5123e19c 100644 --- a/src/vkcv/PipelineManager.cpp +++ b/src/vkcv/PipelineManager.cpp @@ -194,25 +194,28 @@ namespace vkcv std::vector<vk::VertexInputAttributeDescription> vertexAttributeDescriptions; std::vector<vk::VertexInputBindingDescription> vertexBindingDescriptions; - const VertexLayout &layout = config.m_VertexLayout; - - // iterate over the layout's specified, mutually exclusive buffer bindings that make up a vertex buffer - for (const auto &vertexBinding : layout.vertexBindings) - { - vertexBindingDescriptions.emplace_back(vertexBinding.bindingLocation, - vertexBinding.stride, - vk::VertexInputRate::eVertex); - - // iterate over the bindings' specified, mutually exclusive vertex input attachments that make up a vertex - for(const auto &vertexAttachment: vertexBinding.vertexAttachments) - { - vertexAttributeDescriptions.emplace_back(vertexAttachment.inputLocation, - vertexBinding.bindingLocation, - vertexFormatToVulkanFormat(vertexAttachment.format), - vertexAttachment.offset % vertexBinding.stride); + if (existsVertexShader) { + const VertexLayout& layout = config.m_VertexLayout; + + // iterate over the layout's specified, mutually exclusive buffer bindings that make up a vertex buffer + for (const auto& vertexBinding : layout.vertexBindings) + { + vertexBindingDescriptions.emplace_back(vertexBinding.bindingLocation, + vertexBinding.stride, + vk::VertexInputRate::eVertex); + + // iterate over the bindings' specified, mutually exclusive vertex input attachments that make up a vertex + for (const auto& vertexAttachment : vertexBinding.vertexAttachments) + { + vertexAttributeDescriptions.emplace_back(vertexAttachment.inputLocation, + vertexBinding.bindingLocation, + vertexFormatToVulkanFormat(vertexAttachment.format), + vertexAttachment.offset % vertexBinding.stride); + + } + } - } - } + } // Handover Containers to PipelineVertexInputStateCreateIngo Struct vk::PipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo( -- GitLab