Commit ed0c0b5a authored by Vanessa Karolek's avatar Vanessa Karolek
Browse files

Merge branch 'develop' into 42-kamera-trackballkamera

parents df41df65 055a35fb
Pipeline #25715 passed with stages
in 3 minutes and 1 second
......@@ -7,9 +7,9 @@
#include <vector>
#include <cstdint>
#include "vkcv/Handles.hpp"
#include "Handles.hpp"
#include "ShaderProgram.hpp"
#include <vkcv/VertexLayout.hpp>
#include "VertexLayout.hpp"
namespace vkcv {
......@@ -21,24 +21,25 @@ namespace vkcv {
* @param shaderProgram shaders of the pipeline
* @param height height of the application window
* @param width width of the application window
* @param passHandle handle for Render Pass
* @param passHandle handle for render pass
* @param vertexLayout layout of vertex buffer, comprised of its bindings and the bindings' attachments
*/
PipelineConfig(
const ShaderProgram& shaderProgram,
uint32_t width,
uint32_t height,
const PassHandle &passHandle,
const std::vector<VertexAttribute> &vertexAttributes,
const VertexLayout &vertexLayouts,
const std::vector<vk::DescriptorSetLayout> &descriptorLayouts,
bool useDynamicViewport);
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;
bool m_UseDynamicViewport;
ShaderProgram m_ShaderProgram;
uint32_t m_Height;
uint32_t m_Width;
PassHandle m_PassHandle;
VertexLayout m_VertexLayout;
std::vector<vk::DescriptorSetLayout> m_DescriptorLayouts;
bool m_UseDynamicViewport;
};
......
......@@ -12,9 +12,9 @@
#include <filesystem>
#include <vulkan/vulkan.hpp>
#include <spirv_cross.hpp>
#include "vkcv/VertexLayout.hpp"
#include "vkcv/ShaderStage.hpp"
#include "vkcv/DescriptorConfig.hpp"
#include "VertexLayout.hpp"
#include "ShaderStage.hpp"
#include "DescriptorConfig.hpp"
namespace vkcv {
......@@ -48,17 +48,23 @@ namespace vkcv {
bool existsShader(ShaderStage shaderStage) const;
void reflectShader(ShaderStage shaderStage);
const VertexLayout &getVertexLayout() const;
const std::vector<VertexAttachment> &getVertexAttachments() const;
size_t getPushConstantSize() const;
const std::vector<std::vector<DescriptorBinding>> getReflectedDescriptors() const;
const std::vector<std::vector<DescriptorBinding>> &getReflectedDescriptors() const;
private:
/**
* Called after successfully adding a shader to the program.
* Fills vertex input attachments and descriptor sets (if present).
* @param shaderStage the stage to reflect data from
*/
void reflectShader(ShaderStage shaderStage);
std::unordered_map<ShaderStage, Shader> m_Shaders;
VertexLayout m_VertexLayout;
// contains all vertex input attachments used in the vertex buffer
std::vector<VertexAttachment> m_VertexAttachments;
std::vector<std::vector<DescriptorBinding>> m_DescriptorSets;
size_t m_pushConstantSize = 0;
};
......
#pragma once
#include <unordered_map>
#include <vector>
#include <iostream>
#include <string>
namespace vkcv{
/* With these enums, 0 is reserved to signal uninitialized or invalid data. */
enum class PrimitiveType : uint32_t {
UNDEFINED = 0,
POSITION = 1,
NORMAL = 2,
TEXCOORD_0 = 3
};
/* This struct describes one vertex attribute of a vertex buffer. */
typedef struct {
PrimitiveType type; // POSITION, NORMAL, ...
uint32_t offset; // offset in bytes
uint32_t length; // length of ... in bytes
uint32_t stride; // stride in bytes
uint16_t componentType; // eg. 5126 for float
uint8_t componentCount; // eg. 3 for vec3
} VertexAttribute;
enum class VertexFormat{
enum class VertexAttachmentFormat{
FLOAT,
FLOAT2,
FLOAT3,
......@@ -35,23 +16,51 @@ namespace vkcv{
INT4
};
uint32_t getFormatSize(VertexFormat format);
uint32_t getFormatSize(VertexAttachmentFormat format);
struct VertexInputAttachment{
VertexInputAttachment() = delete;
VertexInputAttachment(uint32_t location, uint32_t binding, std::string name, VertexFormat format, uint32_t offset) noexcept;
struct VertexAttachment{
friend struct VertexBinding;
/**
* Describes an individual vertex input attribute/attachment.
* @param inputLocation its location in the vertex shader.
* @param name the name referred to in the shader.
* @param format the format (and therefore, the size) this attachment is in.
* The offset is calculated when a collection of attachments forms a binding, hence the friend declaration.
*/
VertexAttachment(uint32_t inputLocation, const std::string &name, VertexAttachmentFormat format) noexcept;
VertexAttachment() = delete;
uint32_t location;
uint32_t binding;
std::string name;
VertexFormat format;
uint32_t offset;
uint32_t inputLocation;
std::string name;
VertexAttachmentFormat format;
uint32_t offset;
};
struct VertexBinding{
/**
* Describes all vertex input attachments _one_ buffer contains to create a vertex buffer binding.
* NOTE: multiple vertex layouts may contain various (mutually exclusive) vertex input attachments
* to form one complete vertex buffer binding!
* @param bindingLocation its entry in the buffers that make up the whole vertex buffer.
* @param attachments the vertex input attachments this specific buffer layout contains.
*/
VertexBinding(uint32_t bindingLocation, const std::vector<VertexAttachment> &attachments) noexcept;
VertexBinding() = delete;
uint32_t bindingLocation;
uint32_t stride;
std::vector<VertexAttachment> vertexAttachments;
};
struct VertexLayout{
/**
* Describes the complete layout of one vertex, e.g. all of the vertex input attachments used,
* and all of the buffer bindings that refer to the attachments (for when multiple buffers are used).
* @param bindings bindings the complete vertex buffer is comprised of.
*/
VertexLayout() noexcept;
VertexLayout(const std::vector<VertexInputAttachment> &inputs) noexcept;
std::unordered_map<uint32_t, VertexInputAttachment> attachmentMap;
uint32_t stride;
VertexLayout(const std::vector<VertexBinding> &bindings) noexcept;
std::vector<VertexBinding> vertexBindings;
};
}
\ No newline at end of file
......@@ -8,7 +8,6 @@
#include <string>
#include <vector>
#include <cstdint>
#include <vkcv/VertexLayout.hpp>
/* These macros define limits of the following structs. Implementations can
* test against these limits when performing sanity checks. The main constraint
......@@ -53,6 +52,23 @@ enum PrimitiveMode {
/* The indices in the index buffer can be of different bit width. */
enum IndexType { UINT32=0, UINT16=1, UINT8=2 };
/* With these enums, 0 is reserved to signal uninitialized or invalid data. */
enum class PrimitiveType : uint32_t {
UNDEFINED = 0,
POSITION = 1,
NORMAL = 2,
TEXCOORD_0 = 3
};
/* This struct describes one vertex attribute of a vertex buffer. */
typedef struct {
PrimitiveType type; // POSITION, NORMAL, ...
uint32_t offset; // offset in bytes
uint32_t length; // length of ... in bytes
uint32_t stride; // stride in bytes
uint16_t componentType; // eg. 5126 for float
uint8_t componentCount; // eg. 3 for vec3
} VertexAttribute;
typedef struct {
// TODO not yet needed for the first (unlit) triangle
} Material;
......@@ -71,7 +87,7 @@ typedef struct {
} indexBuffer;
struct {
std::vector<uint8_t> data; // binary data of the vertex buffer
std::vector<VertexAttribute> attributes;
std::vector<VertexAttribute> attributes; // description of one
} vertexBuffer;
struct { float x, y, z; } min; // bounding box lower left
struct { float x, y, z; } max; // bounding box upper right
......
......@@ -65,7 +65,7 @@ int main(int argc, const char** argv) {
auto& attributes = mesh.vertexGroups[0].vertexBuffer.attributes;
std::sort(attributes.begin(), attributes.end(), [](const vkcv::VertexAttribute& x, const vkcv::VertexAttribute& y) {
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);
});
......@@ -89,34 +89,41 @@ int main(int argc, const char** argv) {
vk::Format::eD32Sfloat
);
vkcv::PassConfig trianglePassDefinition({ present_color_attachment, depth_attachment });
vkcv::PassHandle trianglePass = core.createPass(trianglePassDefinition);
vkcv::PassConfig firstMeshPassDefinition({ present_color_attachment, depth_attachment });
vkcv::PassHandle firstMeshPass = core.createPass(firstMeshPassDefinition);
if (!trianglePass) {
if (!firstMeshPass) {
std::cout << "Error. Could not create renderpass. Exiting." << std::endl;
return EXIT_FAILURE;
}
vkcv::ShaderProgram triangleShaderProgram{};
triangleShaderProgram.addShader(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/vert.spv"));
triangleShaderProgram.addShader(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("resources/shaders/frag.spv"));
triangleShaderProgram.reflectShader(vkcv::ShaderStage::VERTEX);
triangleShaderProgram.reflectShader(vkcv::ShaderStage::FRAGMENT);
vkcv::ShaderProgram firstMeshProgram{};
firstMeshProgram.addShader(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/vert.spv"));
firstMeshProgram.addShader(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("resources/shaders/frag.spv"));
std::vector<vkcv::DescriptorBinding> descriptorBindings = { triangleShaderProgram.getReflectedDescriptors()[0] };
const std::vector<vkcv::VertexAttachment> vertexAttachments = firstMeshProgram.getVertexAttachments();
std::vector<vkcv::VertexBinding> bindings;
for (size_t i = 0; i < vertexAttachments.size(); i++) {
bindings.push_back(vkcv::VertexBinding(i, { vertexAttachments[i] }));
}
const vkcv::VertexLayout firstMeshLayout (bindings);
std::vector<vkcv::DescriptorBinding> descriptorBindings = { firstMeshProgram.getReflectedDescriptors()[0] };
vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorBindings);
const vkcv::PipelineConfig trianglePipelineDefinition(
triangleShaderProgram,
const vkcv::PipelineConfig firstMeshPipelineConfig(
firstMeshProgram,
windowWidth,
windowHeight,
trianglePass,
attributes,
firstMeshPass,
{firstMeshLayout},
{ core.getDescriptorSet(descriptorSet).layout },
true);
vkcv::PipelineHandle trianglePipeline = core.createGraphicsPipeline(trianglePipelineDefinition);
vkcv::PipelineHandle firstMeshPipeline = core.createGraphicsPipeline(firstMeshPipelineConfig);
if (!trianglePipeline) {
if (!firstMeshPipeline) {
std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl;
return EXIT_FAILURE;
}
......@@ -169,8 +176,6 @@ int main(int argc, const char** argv) {
vkcv::ShaderProgram shadowShader;
shadowShader.addShader(vkcv::ShaderStage::VERTEX, "resources/shaders/shadow_vert.spv");
shadowShader.addShader(vkcv::ShaderStage::FRAGMENT, "resources/shaders/shadow_frag.spv");
shadowShader.reflectShader(vkcv::ShaderStage::VERTEX);
shadowShader.reflectShader(vkcv::ShaderStage::FRAGMENT);
const vk::Format shadowMapFormat = vk::Format::eD16Unorm;
const std::vector<vkcv::AttachmentDescription> shadowAttachments = {
......@@ -185,8 +190,8 @@ int main(int argc, const char** argv) {
shadowShader,
shadowMapResolution,
shadowMapResolution,
shadowPass,
attributes,
shadowPass,
{firstMeshLayout},
{},
false);
const vkcv::PipelineHandle shadowPipe = core.createGraphicsPipeline(shadowPipeConfig);
......@@ -282,8 +287,8 @@ int main(int argc, const char** argv) {
core.recordDrawcallsToCmdStream(
cmdStream,
trianglePass,
trianglePipeline,
firstMeshPass,
firstMeshPipeline,
pushConstantData,
drawcalls,
renderTargets);
......
......@@ -72,41 +72,47 @@ int main(int argc, const char** argv) {
vk::Format::eD32Sfloat
);
vkcv::PassConfig trianglePassDefinition({ present_color_attachment, depth_attachment });
vkcv::PassHandle trianglePass = core.createPass(trianglePassDefinition);
vkcv::PassConfig firstMeshPassDefinition({ present_color_attachment, depth_attachment });
vkcv::PassHandle firstMeshPass = core.createPass(firstMeshPassDefinition);
if (!trianglePass) {
if (!firstMeshPass) {
std::cout << "Error. Could not create renderpass. Exiting." << std::endl;
return EXIT_FAILURE;
}
vkcv::ShaderProgram triangleShaderProgram{};
triangleShaderProgram.addShader(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/vert.spv"));
triangleShaderProgram.addShader(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("resources/shaders/frag.spv"));
triangleShaderProgram.reflectShader(vkcv::ShaderStage::VERTEX);
triangleShaderProgram.reflectShader(vkcv::ShaderStage::FRAGMENT);
vkcv::ShaderProgram firstMeshProgram{};
firstMeshProgram.addShader(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/vert.spv"));
firstMeshProgram.addShader(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("resources/shaders/frag.spv"));
auto& attributes = mesh.vertexGroups[0].vertexBuffer.attributes;
std::sort(attributes.begin(), attributes.end(), [](const vkcv::VertexAttribute& x, const vkcv::VertexAttribute& y) {
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::VertexAttachment> vertexAttachments = firstMeshProgram.getVertexAttachments();
std::vector<vkcv::VertexBinding> bindings;
for (size_t i = 0; i < vertexAttachments.size(); i++) {
bindings.push_back(vkcv::VertexBinding(i, { vertexAttachments[i] }));
}
const vkcv::VertexLayout firstMeshLayout (bindings);
uint32_t setID = 0;
std::vector<vkcv::DescriptorBinding> descriptorBindings = { triangleShaderProgram.getReflectedDescriptors()[setID] };
std::vector<vkcv::DescriptorBinding> descriptorBindings = { firstMeshProgram.getReflectedDescriptors()[setID] };
vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorBindings);
const vkcv::PipelineConfig trianglePipelineDefinition(
triangleShaderProgram,
const vkcv::PipelineConfig firstMeshPipelineConfig(
firstMeshProgram,
UINT32_MAX,
UINT32_MAX,
trianglePass,
mesh.vertexGroups[0].vertexBuffer.attributes,
firstMeshPass,
{firstMeshLayout},
{ core.getDescriptorSet(descriptorSet).layout },
true);
vkcv::PipelineHandle trianglePipeline = core.createGraphicsPipeline(trianglePipelineDefinition);
vkcv::PipelineHandle firstMeshPipeline = core.createGraphicsPipeline(firstMeshPipelineConfig);
if (!trianglePipeline) {
if (!firstMeshPipeline) {
std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl;
return EXIT_FAILURE;
}
......@@ -122,10 +128,9 @@ int main(int argc, const char** argv) {
);
const std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = {
vkcv::VertexBufferBinding( mesh.vertexGroups[0].vertexBuffer.attributes[0].offset, vertexBuffer.getVulkanHandle() ),
vkcv::VertexBufferBinding( mesh.vertexGroups[0].vertexBuffer.attributes[1].offset, vertexBuffer.getVulkanHandle() ),
vkcv::VertexBufferBinding( mesh.vertexGroups[0].vertexBuffer.attributes[2].offset, vertexBuffer.getVulkanHandle() )
};
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.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(0, texture.getHandle()) };
......@@ -178,8 +183,8 @@ int main(int argc, const char** argv) {
core.recordDrawcallsToCmdStream(
cmdStream,
trianglePass,
trianglePipeline,
firstMeshPass,
firstMeshPipeline,
pushConstantData,
{ drawcall },
renderTargets);
......
......@@ -94,8 +94,6 @@ int main(int argc, const char** argv) {
vkcv::ShaderProgram triangleShaderProgram{};
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);
const vkcv::PipelineConfig trianglePipelineDefinition(
triangleShaderProgram,
......@@ -117,7 +115,6 @@ int main(int argc, const char** argv) {
// Compute Pipeline
vkcv::ShaderProgram computeShaderProgram{};
computeShaderProgram.addShader(vkcv::ShaderStage::COMPUTE, std::filesystem::path("shaders/comp.spv"));
computeShaderProgram.reflectShader(vkcv::ShaderStage::COMPUTE);
// take care, assuming shader has exactly one descriptor set
vkcv::DescriptorSetHandle computeDescriptorSet = core.createDescriptorSet(computeShaderProgram.getReflectedDescriptors()[0]);
......
......@@ -13,7 +13,7 @@ namespace vkcv {
uint32_t width,
uint32_t height,
const PassHandle &passHandle,
const std::vector<VertexAttribute> &vertexAttributes,
const VertexLayout &vertexLayout,
const std::vector<vk::DescriptorSetLayout> &descriptorLayouts,
bool useDynamicViewport)
:
......@@ -21,7 +21,7 @@ namespace vkcv {
m_Height(height),
m_Width(width),
m_PassHandle(passHandle),
m_VertexAttributes(vertexAttributes),
m_VertexLayout(vertexLayout),
m_DescriptorLayouts(descriptorLayouts),
m_UseDynamicViewport(useDynamicViewport)
{}
......
......@@ -19,23 +19,23 @@ namespace vkcv
}
// currently assuming default 32 bit formats, no lower precision or normalized variants supported
vk::Format vertexFormatToVulkanFormat(const VertexFormat format) {
vk::Format vertexFormatToVulkanFormat(const VertexAttachmentFormat format) {
switch (format) {
case VertexFormat::FLOAT:
case VertexAttachmentFormat::FLOAT:
return vk::Format::eR32Sfloat;
case VertexFormat::FLOAT2:
case VertexAttachmentFormat::FLOAT2:
return vk::Format::eR32G32Sfloat;
case VertexFormat::FLOAT3:
case VertexAttachmentFormat::FLOAT3:
return vk::Format::eR32G32B32Sfloat;
case VertexFormat::FLOAT4:
case VertexAttachmentFormat::FLOAT4:
return vk::Format::eR32G32B32A32Sfloat;
case VertexFormat::INT:
case VertexAttachmentFormat::INT:
return vk::Format::eR32Sint;
case VertexFormat::INT2:
case VertexAttachmentFormat::INT2:
return vk::Format::eR32G32Sint;
case VertexFormat::INT3:
case VertexAttachmentFormat::INT3:
return vk::Format::eR32G32B32Sint;
case VertexFormat::INT4:
case VertexAttachmentFormat::INT4:
return vk::Format::eR32G32B32A32Sint;
default:
vkcv_log(LogLevel::WARNING, "Unknown vertex format");
......@@ -94,24 +94,24 @@ namespace vkcv
std::vector<vk::VertexInputAttributeDescription> vertexAttributeDescriptions;
std::vector<vk::VertexInputBindingDescription> vertexBindingDescriptions;
VertexLayout layout = config.m_ShaderProgram.getVertexLayout();
std::unordered_map<uint32_t, VertexInputAttachment> attachments = layout.attachmentMap;
const VertexLayout &layout = config.m_VertexLayout;
for (int i = 0; i < attachments.size(); i++) {
VertexInputAttachment &attachment = attachments.at(i);
uint32_t location = attachment.location;
uint32_t binding = i;
vk::Format vertexFormat = vertexFormatToVulkanFormat(attachment.format);
//FIXME: hoping that order is the same and compatible: add explicit mapping and validation
const VertexAttribute attribute = config.m_VertexAttributes[i];
vertexAttributeDescriptions.emplace_back(location, binding, vertexFormatToVulkanFormat(attachment.format), 0);
vertexBindingDescriptions.emplace_back(vk::VertexInputBindingDescription(
binding,
attribute.stride + getFormatSize(attachment.format),
vk::VertexInputRate::eVertex));
// 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
......
......@@ -28,18 +28,18 @@ namespace vkcv {
return buffer;
}
VertexFormat convertFormat(spirv_cross::SPIRType::BaseType basetype, uint32_t vecsize){
VertexAttachmentFormat convertFormat(spirv_cross::SPIRType::BaseType basetype, uint32_t vecsize){
switch (basetype) {
case spirv_cross::SPIRType::Int:
switch (vecsize) {
case 1:
return VertexFormat::INT;
return VertexAttachmentFormat::INT;
case 2:
return VertexFormat::INT2;
return VertexAttachmentFormat::INT2;
case 3:
return VertexFormat::INT3;
return VertexAttachmentFormat::INT3;
case 4:
return VertexFormat::INT4;
return VertexAttachmentFormat::INT4;
default:
break;
}
......@@ -47,13 +47,13 @@ namespace vkcv {
case spirv_cross::SPIRType::Float:
switch (vecsize) {
case 1:
return VertexFormat::FLOAT;
return VertexAttachmentFormat::FLOAT;
case 2:
return VertexFormat::FLOAT2;
return VertexAttachmentFormat::FLOAT2;
case 3:
return VertexFormat::FLOAT3;
return VertexAttachmentFormat::FLOAT3;
case 4:
return VertexFormat::FLOAT4;
return VertexAttachmentFormat::FLOAT4;
default:
break;
}
......@@ -63,12 +63,12 @@ namespace vkcv {
}
vkcv_log(LogLevel::WARNING, "Unknown vertex format");
return VertexFormat::FLOAT;
return VertexAttachmentFormat::FLOAT;
}
ShaderProgram::ShaderProgram() noexcept :
m_Shaders{},
m_VertexLayout{},
m_VertexAttachments{},
m_DescriptorSets{}
{}
......@@ -85,6 +85,7 @@ namespace vkcv {
} else {
Shader shader{shaderCode, shaderStage};
m_Shaders.insert(std::make_pair(shaderStage, shader));
reflectShader(shaderStage);
return true;
}
}
......@@ -107,30 +108,31 @@ namespace vkcv {
auto shaderCodeChar = m_Shaders.at(shaderStage).shaderCode;
std::vector<uint32_t> shaderCode;
for (uint32_t i = 0; i < shaderCodeChar.size()/4; 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::ShaderResources resources = comp.get_shader_resources();
//reflect vertex input
if (shaderStage == ShaderStage::VERTEX) {
std::vector<VertexInputAttachment> inputVec;
uint32_t offset = 0;