From aad45984b1f9f2383bda074a4d35fe1160c6ef03 Mon Sep 17 00:00:00 2001 From: Leonie Franken <lfranken@uni-koblenz.de> Date: Fri, 28 May 2021 13:14:17 +0200 Subject: [PATCH] [#36] vertex layout reflection done --- config/Sources.cmake | 3 ++ include/vkcv/ShaderProgram.hpp | 6 ++- include/vkcv/VertexLayout.hpp | 37 ++++++++++++++++ src/vkcv/ShaderProgram.cpp | 78 +++++++++++++++++++++++++++------- src/vkcv/VertexLayout.cpp | 53 +++++++++++++++++++++++ 5 files changed, 161 insertions(+), 16 deletions(-) create mode 100644 include/vkcv/VertexLayout.hpp create mode 100644 src/vkcv/VertexLayout.cpp diff --git a/config/Sources.cmake b/config/Sources.cmake index 0d0a3787..63178767 100644 --- a/config/Sources.cmake +++ b/config/Sources.cmake @@ -51,4 +51,7 @@ set(vkcv_sources ${vkcv_source}/vkcv/Framebuffer.hpp ${vkcv_source}/vkcv/Framebuffer.cpp + + ${vkcv_include}/vkcv/VertexLayout.hpp + ${vkcv_source}/vkcv/VertexLayout.cpp ) diff --git a/include/vkcv/ShaderProgram.hpp b/include/vkcv/ShaderProgram.hpp index 0a8470a9..af60f9fb 100644 --- a/include/vkcv/ShaderProgram.hpp +++ b/include/vkcv/ShaderProgram.hpp @@ -11,6 +11,7 @@ #include <filesystem> #include <vulkan/vulkan.hpp> #include <spirv_cross.hpp> +#include "vkcv/VertexLayout.hpp" namespace vkcv { @@ -54,10 +55,13 @@ namespace vkcv { bool existsShader(ShaderStage shaderStage) const; - void reflectShader(ShaderStage shaderStage) const; + void reflectShader(ShaderStage shaderStage); + + VertexLayout& getVertexLayout(); private: std::unordered_map<ShaderStage, Shader> m_Shaders; + VertexLayout m_VertexLayout; }; } diff --git a/include/vkcv/VertexLayout.hpp b/include/vkcv/VertexLayout.hpp new file mode 100644 index 00000000..f9579b5d --- /dev/null +++ b/include/vkcv/VertexLayout.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include <unordered_map> +#include <vector> +#include <iostream> + +namespace vkcv{ + enum class VertexFormat{ + FLOAT, + FLOAT2, + FLOAT3, + FLOAT4, + INT, + INT2, + INT3, + INT4 + }; + + struct VertexInputAttachment{ + VertexInputAttachment() = delete; + VertexInputAttachment(uint32_t location, uint32_t binding, VertexFormat format, uint32_t offset) noexcept; + + uint32_t location; + uint32_t binding; + VertexFormat format; + uint32_t offset; + }; + + struct VertexLayout{ + VertexLayout() noexcept; + VertexLayout(const std::vector<VertexInputAttachment> &inputs) noexcept; + std::unordered_map<uint32_t, VertexInputAttachment> attachmentMap; + uint32_t stride; + }; + + +} \ No newline at end of file diff --git a/src/vkcv/ShaderProgram.cpp b/src/vkcv/ShaderProgram.cpp index fce6ea35..69ad7c31 100644 --- a/src/vkcv/ShaderProgram.cpp +++ b/src/vkcv/ShaderProgram.cpp @@ -27,8 +27,46 @@ namespace vkcv { return buffer; } + VertexFormat convertFormat(spirv_cross::SPIRType::BaseType basetype, uint32_t vecsize){ + switch (basetype) { + case spirv_cross::SPIRType::Int: + switch (vecsize) { + case 1: + return VertexFormat::INT; + case 2: + return VertexFormat::INT2; + case 3: + return VertexFormat::INT3; + case 4: + return VertexFormat::INT4; + default: + break; + } + break; + case spirv_cross::SPIRType::Float: + switch (vecsize) { + case 1: + return VertexFormat::FLOAT; + case 2: + return VertexFormat::FLOAT2; + case 3: + return VertexFormat::FLOAT3; + case 4: + return VertexFormat::FLOAT4; + default: + break; + } + break; + default: + break; + } + std::cout << "Shader Program Reflection: unknown Vertex Format" << std::endl; + return VertexFormat::FLOAT; + } + ShaderProgram::ShaderProgram() noexcept : - m_Shaders{} + m_Shaders{}, + m_VertexLayout{} {} bool ShaderProgram::addShader(ShaderStage shaderStage, const std::filesystem::path &shaderPath) @@ -60,27 +98,37 @@ namespace vkcv { return true; } - void ShaderProgram::reflectShader(ShaderStage shaderStage) const + void ShaderProgram::reflectShader(ShaderStage shaderStage) { auto shaderCodeChar = m_Shaders.at(shaderStage).shaderCode; - std::vector<uint32_t> shaderCode; //convert from char to uint 32. Is this the best way? Prob not. + std::vector<uint32_t> shaderCode; - for (uint32_t i = 0; i < shaderCodeChar.size(); i++) { - shaderCode.push_back((uint32_t) shaderCodeChar[i]); + for (uint32_t i = 0; i < shaderCodeChar.size()/4; i++) { + shaderCode.push_back(((uint32_t*) shaderCodeChar.data())[i]); } - //spirv_cross::Compiler comp(move(shaderCode)); - - /* + spirv_cross::Compiler comp(move(shaderCode)); spirv_cross::ShaderResources resources = comp.get_shader_resources(); - //testprint - for (auto &u : resources.uniform_buffers) - { - uint32_t set = comp.get_decoration(u.id, spv::DecorationDescriptorSet); - uint32_t binding = comp.get_decoration(u.id, spv::DecorationBinding); - std::cout << 'Found UBO ' << &u << ' at set = ' << set << ', binding = ' << binding << std::endl; + std::vector<VertexInputAttachment> inputVec; + uint32_t offset = 0; + + for (uint32_t i = 0; i < resources.stage_inputs.size() ; i++){ + auto &u = resources.stage_inputs[i]; + const spirv_cross::SPIRType &base_type = comp.get_type(u.base_type_id); + + VertexInputAttachment input = VertexInputAttachment(comp.get_decoration(u.id,spv::DecorationLocation), + 0, + convertFormat(base_type.basetype, base_type.vecsize), + offset); + inputVec.push_back(input); + offset += base_type.vecsize * base_type.width/8; } - */ + + m_VertexLayout = VertexLayout(inputVec); } + + VertexLayout& ShaderProgram::getVertexLayout(){ + return m_VertexLayout; + } } diff --git a/src/vkcv/VertexLayout.cpp b/src/vkcv/VertexLayout.cpp new file mode 100644 index 00000000..88c9406b --- /dev/null +++ b/src/vkcv/VertexLayout.cpp @@ -0,0 +1,53 @@ +// +// Created by Charlotte on 28.05.2021. +// + +#include "vkcv/VertexLayout.hpp" + +namespace vkcv { + uint32_t static getFormatSize(VertexFormat format) { + switch (format) { + case VertexFormat::FLOAT: + return 4; + case VertexFormat::FLOAT2: + return 8; + case VertexFormat::FLOAT3: + return 12; + case VertexFormat::FLOAT4: + return 16; + case VertexFormat::INT: + return 4; + case VertexFormat::INT2: + return 8; + case VertexFormat::INT3: + return 12; + case VertexFormat::INT4: + return 16; + default: + break; + } + std::cout << "VertexLayout: No format given" << std::endl; + return 0; + } + + VertexInputAttachment::VertexInputAttachment(uint32_t location, uint32_t binding, VertexFormat format, uint32_t offset) noexcept: + location{location}, + binding{binding}, + format{format}, + offset{offset} + {} + + VertexLayout::VertexLayout() noexcept : + stride{0}, + attachmentMap() + {} + + VertexLayout::VertexLayout(const std::vector<VertexInputAttachment> &inputs) noexcept { + stride = 0; + for (const auto &input : inputs) { + attachmentMap.insert(std::make_pair(input.location, input)); + stride += getFormatSize(input.format); + } + } + +} \ No newline at end of file -- GitLab