Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • vulkan2021/vkcv-framework
1 result
Select Git revision
Show changes
Showing
with 213 additions and 371 deletions
......@@ -11,14 +11,6 @@ vkcv::DescriptorSetHandle PipelineInit::ComputePipelineInit(vkcv::Core *pCore, v
shaderProgram.getReflectedDescriptors().at(0));
vkcv::DescriptorSetHandle descriptorSet = pCore->createDescriptorSet(descriptorSetLayout);
const std::vector<vkcv::VertexAttachment> vertexAttachments = shaderProgram.getVertexAttachments();
std::vector<vkcv::VertexBinding> bindings;
for (size_t i = 0; i < vertexAttachments.size(); i++) {
bindings.push_back(vkcv::createVertexBinding(i, { vertexAttachments[i] }));
}
const vkcv::VertexLayout layout { bindings };
pipeline = pCore->createComputePipeline({
shaderProgram,
{ descriptorSetLayout }
......
......@@ -98,40 +98,17 @@ int main(int argc, const char **argv) {
particleShaderProgram.getReflectedDescriptors().at(0));
vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorSetLayout);
vkcv::Buffer<glm::vec3> vertexBuffer = core.createBuffer<glm::vec3>(
vkcv::BufferType::VERTEX,
3
);
const std::vector<vkcv::VertexAttachment> vertexAttachments = particleShaderProgram.getVertexAttachments();
const std::vector<vkcv::VertexBufferBinding> vertexBufferBindings = {
vkcv::VertexBufferBinding(0, vertexBuffer.getVulkanHandle())};
std::vector<vkcv::VertexBinding> bindings;
for (size_t i = 0; i < vertexAttachments.size(); i++) {
bindings.push_back(vkcv::createVertexBinding(i, {vertexAttachments[i]}));
}
const vkcv::VertexLayout particleLayout { bindings };
// initializing graphics pipeline
vkcv::GraphicsPipelineConfig particlePipelineDefinition{
particleShaderProgram,
UINT32_MAX,
UINT32_MAX,
particlePass,
{particleLayout},
{descriptorSetLayout},
true
};
particlePipelineDefinition.m_blendMode = vkcv::BlendMode::Additive;
const std::vector<glm::vec3> vertices = {glm::vec3(-0.012, 0.012, 0),
glm::vec3(0.012, 0.012, 0),
glm::vec3(0, -0.012, 0)};
vertexBuffer.fill(vertices);
vkcv::GraphicsPipelineHandle particlePipeline = core.createGraphicsPipeline(particlePipelineDefinition);
vkcv::Buffer<glm::vec4> color = core.createBuffer<glm::vec4>(
......@@ -205,7 +182,7 @@ int main(int argc, const char **argv) {
const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle();
const vkcv::Mesh renderMesh({vertexBufferBindings}, particleIndexBuffer.getVulkanHandle(),
const vkcv::Mesh renderMesh(particleIndexBuffer.getVulkanHandle(),
particleIndexBuffer.getCount());
vkcv::DescriptorSetUsage descriptorUsage(0, descriptorSet);
......
......@@ -3,8 +3,11 @@
#extension GL_GOOGLE_include_directive : enable
layout(location = 0) in vec3 inPosition;
layout(location = 2) in vec2 inUV;
#include "vertex.inc"
layout(std430, set=2, binding=0) readonly buffer buffer_vertexBuffer {
vertex_t vertices [];
};
layout(location = 0) out vec2 passUV;
......@@ -13,6 +16,6 @@ layout( push_constant ) uniform constants{
};
void main() {
gl_Position = mvp * vec4(inPosition, 1.0);
passUV = inUV;
gl_Position = mvp * vec4(vertices[gl_VertexIndex].position, 1.0);
passUV = vec2(vertices[gl_VertexIndex].u, vertices[gl_VertexIndex].v);
}
\ No newline at end of file
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec2 inUV;
layout(location = 3) in vec4 inTangent;
#extension GL_GOOGLE_include_directive : enable
#include "vertex.inc"
layout(std430, set=2, binding=0) readonly buffer buffer_vertexBuffer {
vertex_t vertices [];
};
layout(location = 0) out vec3 passNormal;
layout(location = 1) out vec2 passUV;
......@@ -17,9 +20,12 @@ layout( push_constant ) uniform constants{
};
void main() {
gl_Position = mvp * vec4(inPosition, 1.0);
passNormal = mat3(model) * inNormal; // assuming no weird stuff like shearing or non-uniform scaling
passUV = inUV;
passPos = (model * vec4(inPosition, 1)).xyz;
passTangent = vec4(mat3(model) * inTangent.xyz, inTangent.w);
vec3 position = vertices[gl_VertexIndex].position;
vec4 tangent = vertices[gl_VertexIndex].tangent;
gl_Position = mvp * vec4(position, 1.0);
passNormal = mat3(model) * vertices[gl_VertexIndex].normal; // assuming no weird stuff like shearing or non-uniform scaling
passUV = vec2(vertices[gl_VertexIndex].u, vertices[gl_VertexIndex].v);
passPos = (model * vec4(position, 1)).xyz;
passTangent = vec4(mat3(model) * tangent.xyz, tangent.w);
}
\ No newline at end of file
......@@ -3,12 +3,16 @@
#extension GL_GOOGLE_include_directive : enable
layout(location = 0) in vec3 inPosition;
#include "vertex.inc"
layout(std430, set=0, binding=0) readonly buffer buffer_vertexBuffer {
vertex_t vertices [];
};
layout( push_constant ) uniform constants{
mat4 mvp;
};
void main() {
gl_Position = mvp * vec4(inPosition, 1.0);
gl_Position = mvp * vec4(vertices[gl_VertexIndex].position, 1.0);
}
\ No newline at end of file
#ifndef VERTEX_INC
#define VERTEX_INC
struct vertex_t {
vec3 position;
float u;
vec3 normal;
float v;
vec4 tangent;
};
#endif // #ifndef VERTEX_INC
\ No newline at end of file
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec2 inUV;
#extension GL_GOOGLE_include_directive : enable
#include "vertex.inc"
layout(std430, set=2, binding=0) readonly buffer buffer_vertexBuffer {
vertex_t vertices [];
};
layout(location = 0) out vec3 passPos;
layout(location = 1) out vec2 passUV;
......@@ -15,8 +19,8 @@ layout( push_constant ) uniform constants{
};
void main() {
gl_Position = mvp * vec4(inPosition, 1.0);
passPos = (model * vec4(inPosition, 1)).xyz;
passUV = inUV;
passN = mat3(model) * inNormal;
gl_Position = mvp * vec4(vertices[gl_VertexIndex].position, 1.0);
passPos = (model * vec4(vertices[gl_VertexIndex].position, 1)).xyz;
passUV = vec2(vertices[gl_VertexIndex].u, vertices[gl_VertexIndex].v);
passN = mat3(model) * vertices[gl_VertexIndex].normal;
}
\ No newline at end of file
......@@ -149,7 +149,7 @@ glm::mat4 computeShadowViewProjectionMatrix(
return vulkanCorrectionMatrix * crop * view;
}
ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vertexLayout) :
ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::DescriptorSetLayoutHandle &layoutHandle) :
m_corePtr(corePtr),
m_shadowMap(corePtr->createImage(shadowMapFormat, shadowMapResolution, shadowMapResolution, 1, true, true)),
m_shadowMapIntermediate(corePtr->createImage(shadowMapFormat, shadowMapResolution, shadowMapResolution, 1, false, true)),
......@@ -171,8 +171,7 @@ ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vert
shadowMapResolution,
shadowMapResolution,
m_shadowMapPass,
vertexLayout,
{},
{ layoutHandle },
false
};
shadowPipeConfig.m_multisampling = msaa;
......@@ -232,6 +231,7 @@ void ShadowMapping::recordShadowMapRendering(
float lightStrength,
float maxShadowDistance,
const std::vector<vkcv::Mesh>& meshes,
const std::vector<vkcv::DescriptorSetHandle> &vertexDescriptorSets,
const std::vector<glm::mat4>& modelMatrices,
const vkcv::camera::Camera& camera,
const glm::vec3& voxelVolumeOffset,
......@@ -262,8 +262,14 @@ void ShadowMapping::recordShadowMapRendering(
}
std::vector<vkcv::DrawcallInfo> drawcalls;
drawcalls.reserve(meshes.size());
for (const auto& mesh : meshes) {
drawcalls.push_back(vkcv::DrawcallInfo(mesh, {}));
const size_t meshIndex = drawcalls.size();
drawcalls.push_back(vkcv::DrawcallInfo(mesh, {
vkcv::DescriptorSetUsage(0, vertexDescriptorSets[meshIndex])
}));
}
m_corePtr->recordBeginDebugLabel(cmdStream, "Shadow map depth", {1, 1, 1, 1});
......
......@@ -17,7 +17,7 @@ struct LightInfo {
class ShadowMapping {
public:
ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vertexLayout);
ShadowMapping(vkcv::Core* corePtr, const vkcv::DescriptorSetLayoutHandle &layoutHandle);
void recordShadowMapRendering(
const vkcv::CommandStreamHandle& cmdStream,
......@@ -26,6 +26,7 @@ public:
float lightStrength,
float maxShadowDistance,
const std::vector<vkcv::Mesh>& meshes,
const std::vector<vkcv::DescriptorSetHandle> &vertexDescriptorSets,
const std::vector<glm::mat4>& modelMatrices,
const vkcv::camera::Camera& camera,
const glm::vec3& voxelVolumeOffset,
......
......@@ -81,7 +81,8 @@ Voxelization::Voxelization(
vkcv::ImageHandle shadowMap,
vkcv::SamplerHandle shadowSampler,
vkcv::SamplerHandle voxelSampler,
vkcv::Multisampling msaa)
vkcv::Multisampling msaa,
const vkcv::DescriptorSetLayoutHandle &layoutHandle)
:
m_corePtr(corePtr),
m_voxelImageIntermediate(m_corePtr->createImage(vk::Format::eR16G16B16A16Sfloat, voxelResolution, voxelResolution, voxelResolution, true, true)),
......@@ -105,15 +106,13 @@ Voxelization::Voxelization(
m_voxelizationDescriptorSet = m_corePtr->createDescriptorSet(m_voxelizationDescriptorSetLayout);
vkcv::DescriptorSetLayoutHandle dummyPerMeshDescriptorSetLayout = m_corePtr->createDescriptorSetLayout(voxelizationShader.getReflectedDescriptors().at(1));
vkcv::DescriptorSetHandle dummyPerMeshDescriptorSet = m_corePtr->createDescriptorSet(dummyPerMeshDescriptorSetLayout);
const vkcv::GraphicsPipelineConfig voxelizationPipeConfig{
voxelizationShader,
voxelResolution,
voxelResolution,
m_voxelizationPass,
dependencies.vertexLayout,
{ m_voxelizationDescriptorSetLayout, dummyPerMeshDescriptorSetLayout },
{ m_voxelizationDescriptorSetLayout, dummyPerMeshDescriptorSetLayout, layoutHandle },
false,
true
};
......@@ -161,7 +160,6 @@ Voxelization::Voxelization(
0,
0,
m_visualisationPass,
{},
{ m_visualisationDescriptorSetLayout },
true,
false,
......@@ -229,6 +227,7 @@ void Voxelization::voxelizeMeshes(
const std::vector<vkcv::Mesh>& meshes,
const std::vector<glm::mat4>& modelMatrices,
const std::vector<vkcv::DescriptorSetHandle>& perMeshDescriptorSets,
const std::vector<vkcv::DescriptorSetHandle>& vertexDescriptorSets,
const vkcv::WindowHandle& windowHandle,
vkcv::Downsampler& downsampler) {
......@@ -279,7 +278,8 @@ void Voxelization::voxelizeMeshes(
meshes[i],
{
vkcv::DescriptorSetUsage(0, m_voxelizationDescriptorSet),
vkcv::DescriptorSetUsage(1, perMeshDescriptorSets[i])
vkcv::DescriptorSetUsage(1, perMeshDescriptorSets[i]),
vkcv::DescriptorSetUsage(2, vertexDescriptorSets[i])
},1));
}
......@@ -357,7 +357,7 @@ void Voxelization::renderVoxelVisualisation(
uint32_t drawVoxelCount = voxelCount / exp2(mipLevel);
const auto drawcall = vkcv::DrawcallInfo(
vkcv::Mesh({}, nullptr, drawVoxelCount),
vkcv::Mesh(nullptr, drawVoxelCount),
{ vkcv::DescriptorSetUsage(0, m_visualisationDescriptorSet) },1);
m_corePtr->recordBeginDebugLabel(cmdStream, "Voxel visualisation", { 1, 1, 1, 1 });
......
......@@ -7,10 +7,10 @@
class Voxelization{
public:
struct Dependencies {
vkcv::VertexLayout vertexLayout;
vk::Format colorBufferFormat;
vk::Format depthBufferFormat;
};
Voxelization(
vkcv::Core* corePtr,
const Dependencies& dependencies,
......@@ -18,13 +18,15 @@ public:
vkcv::ImageHandle shadowMap,
vkcv::SamplerHandle shadowSampler,
vkcv::SamplerHandle voxelSampler,
vkcv::Multisampling msaa);
vkcv::Multisampling msaa,
const vkcv::DescriptorSetLayoutHandle& layoutHandle);
void voxelizeMeshes(
vkcv::CommandStreamHandle cmdStream,
const std::vector<vkcv::Mesh>& meshes,
const std::vector<glm::mat4>& modelMatrices,
const std::vector<vkcv::DescriptorSetHandle>& perMeshDescriptorSets,
const std::vector<vkcv::DescriptorSetHandle>& vertexDescriptorSets,
const vkcv::WindowHandle& windowHandle,
vkcv::Downsampler& downsampler);
......
......@@ -14,6 +14,12 @@
#include <vkcv/effects/BloomAndFlaresEffect.hpp>
#include <vkcv/algorithm/SinglePassDownsampler.hpp>
struct vertex_t {
float positionU [4];
float normalV [4];
float tangent [4];
};
int main(int argc, const char** argv) {
const char* applicationName = "Voxelization";
......@@ -132,31 +138,91 @@ int main(int argc, const char** argv) {
// build index and vertex buffers
assert(!scene.vertexGroups.empty());
std::vector<std::vector<uint8_t>> vBuffers;
std::vector<std::vector<uint8_t>> iBuffers;
std::vector<vkcv::VertexBufferBinding> vBufferBindings;
std::vector<std::vector<vkcv::VertexBufferBinding>> vertexBufferBindings;
std::vector<vkcv::asset::VertexAttribute> vAttributes;
for (size_t i = 0; i < scene.vertexGroups.size(); i++) {
vBuffers.push_back(scene.vertexGroups[i].vertexBuffer.data);
iBuffers.push_back(scene.vertexGroups[i].indexBuffer.data);
auto& attributes = scene.vertexGroups[i].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);
});
}
std::vector<vkcv::Buffer<uint8_t>> vertexBuffers;
std::vector<vkcv::Buffer<vertex_t>> vertexBuffers;
vertexBuffers.reserve(scene.vertexGroups.size());
for (const vkcv::asset::VertexGroup& group : scene.vertexGroups) {
vertexBuffers.push_back(core.createBuffer<uint8_t>(
vkcv::BufferType::VERTEX,
group.vertexBuffer.data.size()));
vertexBuffers.back().fill(group.vertexBuffer.data);
vertexBuffers.push_back(core.createBuffer<vertex_t>(
vkcv::BufferType::STORAGE,
group.numVertices));
std::vector<vertex_t> vertices;
vertices.reserve(group.numVertices);
for (const auto& attribute : group.vertexBuffer.attributes) {
if (attribute.componentType != vkcv::asset::ComponentType::FLOAT32) {
continue;
}
size_t offset = attribute.offset;
for (size_t i = 0; i < group.numVertices; i++) {
const auto *data = reinterpret_cast<const float*>(
group.vertexBuffer.data.data() + offset
);
switch (attribute.type) {
case vkcv::asset::PrimitiveType::POSITION:
memcpy(vertices[i].positionU, data, sizeof(float) * attribute.componentCount);
break;
case vkcv::asset::PrimitiveType::NORMAL:
memcpy(vertices[i].normalV, data, sizeof(float) * attribute.componentCount);
break;
case vkcv::asset::PrimitiveType::TEXCOORD_0:
if (attribute.componentCount != 2) {
break;
}
vertices[i].positionU[3] = data[0];
vertices[i].normalV[3] = data[1];
break;
case vkcv::asset::PrimitiveType::TANGENT:
memcpy(vertices[i].tangent, data, sizeof(float) * attribute.componentCount);
break;
default:
break;
}
offset += attribute.stride;
}
}
vertexBuffers.back().fill(vertices);
}
vkcv::DescriptorBindings vertexDescriptorBindings;
vertexDescriptorBindings.insert(std::make_pair(0, vkcv::DescriptorBinding{
0,
vkcv::DescriptorType::STORAGE_BUFFER,
1,
vkcv::ShaderStage::VERTEX,
false,
false
}));
vkcv::DescriptorSetLayoutHandle vertexDescriptorSetLayout = core.createDescriptorSetLayout(
vertexDescriptorBindings
);
std::vector<vkcv::DescriptorSetHandle> vertexDescriptorSets;
vertexDescriptorSets.reserve(vertexBuffers.size());
for (const auto& buffer : vertexBuffers) {
auto descriptorSet = core.createDescriptorSet(vertexDescriptorSetLayout);
vkcv::DescriptorWrites writes;
writes.writeStorageBuffer(0, buffer.getHandle());
core.writeDescriptorSet(descriptorSet, writes);
vertexDescriptorSets.push_back(descriptorSet);
}
std::vector<vkcv::Buffer<uint8_t>> indexBuffers;
......@@ -167,17 +233,6 @@ int main(int argc, const char** argv) {
indexBuffers.back().fill(dataBuffer);
}
int vertexBufferIndex = 0;
for (const auto& vertexGroup : scene.vertexGroups) {
for (const auto& attribute : vertexGroup.vertexBuffer.attributes) {
vAttributes.push_back(attribute);
vBufferBindings.push_back(vkcv::VertexBufferBinding(attribute.offset, vertexBuffers[vertexBufferIndex].getVulkanHandle()));
}
vertexBufferBindings.push_back(vBufferBindings);
vBufferBindings.clear();
vertexBufferIndex++;
}
const vk::Format colorBufferFormat = vk::Format::eB10G11R11UfloatPack32;
const vkcv::AttachmentDescription color_attachment(
vkcv::AttachmentOperation::STORE,
......@@ -208,14 +263,6 @@ int main(int argc, const char** argv) {
forwardProgram.addShader(shaderStage, path);
});
const std::vector<vkcv::VertexAttachment> vertexAttachments = forwardProgram.getVertexAttachments();
std::vector<vkcv::VertexBinding> vertexBindings;
for (size_t i = 0; i < vertexAttachments.size(); i++) {
vertexBindings.push_back(vkcv::createVertexBinding(i, { vertexAttachments[i] }));
}
const vkcv::VertexLayout vertexLayout { vertexBindings };
vkcv::DescriptorSetLayoutHandle forwardShadingDescriptorSetLayout = core.createDescriptorSetLayout(forwardProgram.getReflectedDescriptors().at(0));
vkcv::DescriptorSetHandle forwardShadingDescriptorSet = core.createDescriptorSet(forwardShadingDescriptorSetLayout);
......@@ -230,14 +277,6 @@ int main(int argc, const char** argv) {
depthPrepassShader.addShader(shaderStage, path);
});
const std::vector<vkcv::VertexAttachment> prepassVertexAttachments = depthPrepassShader.getVertexAttachments();
std::vector<vkcv::VertexBinding> prepassVertexBindings;
for (size_t i = 0; i < prepassVertexAttachments.size(); i++) {
prepassVertexBindings.push_back(vkcv::createVertexBinding(i, { prepassVertexAttachments[i] }));
}
const vkcv::VertexLayout prepassVertexLayout { prepassVertexBindings };
const vkcv::AttachmentDescription prepassAttachment(
vkcv::AttachmentOperation::STORE,
vkcv::AttachmentOperation::CLEAR,
......@@ -259,7 +298,6 @@ int main(int argc, const char** argv) {
std::vector<vkcv::Image> sceneImages;
vkcv::algorithm::SinglePassDownsampler spdDownsampler (core, colorSampler);
vkcv::Downsampler &downsampler = core.getDownsampler();
auto mipStream = core.createCommandStream(vkcv::QueueType::Graphics);
......@@ -339,8 +377,7 @@ int main(int argc, const char** argv) {
swapchainExtent.width,
swapchainExtent.height,
prepassPass,
vertexLayout,
{ prepassDescriptorSetLayout, perMeshDescriptorSetLayouts[0] },
{ prepassDescriptorSetLayout, perMeshDescriptorSetLayouts[0], vertexDescriptorSetLayout },
true
};
prepassPipelineConfig.m_culling = vkcv::CullMode::Back;
......@@ -356,8 +393,7 @@ int main(int argc, const char** argv) {
swapchainExtent.width,
swapchainExtent.height,
forwardPass,
vertexLayout,
{ forwardShadingDescriptorSetLayout, perMeshDescriptorSetLayouts[0] },
{ forwardShadingDescriptorSetLayout, perMeshDescriptorSetLayouts[0], vertexDescriptorSetLayout },
true
};
forwardPipelineConfig.m_culling = vkcv::CullMode::Back;
......@@ -409,7 +445,6 @@ int main(int argc, const char** argv) {
skyPipeConfig.m_Width = swapchainExtent.width;
skyPipeConfig.m_Height = swapchainExtent.height;
skyPipeConfig.m_PassHandle = skyPass;
skyPipeConfig.m_VertexLayout = vkcv::VertexLayout();
skyPipeConfig.m_DescriptorLayouts = {};
skyPipeConfig.m_UseDynamicViewport = true;
skyPipeConfig.m_multisampling = msaa;
......@@ -541,7 +576,7 @@ int main(int argc, const char** argv) {
// prepare meshes
std::vector<vkcv::Mesh> meshes;
for (size_t i = 0; i < scene.vertexGroups.size(); i++) {
vkcv::Mesh mesh(vertexBufferBindings[i], indexBuffers[i].getVulkanHandle(), scene.vertexGroups[i].numIndices);
vkcv::Mesh mesh(indexBuffers[i].getVulkanHandle(), scene.vertexGroups[i].numIndices);
meshes.push_back(mesh);
}
......@@ -551,10 +586,14 @@ int main(int argc, const char** argv) {
drawcalls.push_back(vkcv::DrawcallInfo(meshes[i], {
vkcv::DescriptorSetUsage(0, forwardShadingDescriptorSet),
vkcv::DescriptorSetUsage(1, perMeshDescriptorSets[i]) }));
vkcv::DescriptorSetUsage(1, perMeshDescriptorSets[i]),
vkcv::DescriptorSetUsage(2, vertexDescriptorSets[i])
}));
prepassDrawcalls.push_back(vkcv::DrawcallInfo(meshes[i], {
vkcv::DescriptorSetUsage(0, prepassDescriptorSet),
vkcv::DescriptorSetUsage(1, perMeshDescriptorSets[i]) }));
vkcv::DescriptorSetUsage(1, perMeshDescriptorSets[i]),
vkcv::DescriptorSetUsage(2, vertexDescriptorSets[i])
}));
}
vkcv::SamplerHandle voxelSampler = core.createSampler(
......@@ -564,12 +603,11 @@ int main(int argc, const char** argv) {
vkcv::SamplerAddressMode::CLAMP_TO_EDGE
);
ShadowMapping shadowMapping(&core, vertexLayout);
ShadowMapping shadowMapping(&core, vertexDescriptorSetLayout);
Voxelization::Dependencies voxelDependencies;
voxelDependencies.colorBufferFormat = colorBufferFormat;
voxelDependencies.depthBufferFormat = depthBufferFormat;
voxelDependencies.vertexLayout = vertexLayout;
Voxelization voxelization(
&core,
voxelDependencies,
......@@ -577,7 +615,8 @@ int main(int argc, const char** argv) {
shadowMapping.getShadowMap(),
shadowMapping.getShadowSampler(),
voxelSampler,
msaa);
msaa,
vertexDescriptorSetLayout);
vkcv::effects::BloomAndFlaresEffect bloomFlares (core, true);
vkcv::Buffer<glm::vec3> cameraPosBuffer = core.createBuffer<glm::vec3>(vkcv::BufferType::UNIFORM, 1);
......@@ -778,6 +817,7 @@ int main(int argc, const char** argv) {
lightStrength,
maxShadowDistance,
meshes,
vertexDescriptorSets,
modelMatrices,
cameraManager.getActiveCamera(),
voxelization.getVoxelOffset(),
......@@ -793,6 +833,7 @@ int main(int argc, const char** argv) {
meshes,
modelMatrices,
perMeshDescriptorSets,
vertexDescriptorSets,
windowHandle,
spdDownsampler
);
......@@ -863,7 +904,7 @@ int main(int argc, const char** argv) {
skyPass,
skyPipe,
skySettingsPushConstants,
{ vkcv::DrawcallInfo(vkcv::Mesh({}, nullptr, 3), {}) },
{ vkcv::DrawcallInfo(vkcv::Mesh(nullptr, 3), {}) },
renderTargets,
windowHandle);
core.recordEndDebugLabel(cmdStream);
......
......@@ -10,8 +10,6 @@ layout(set=0, binding=2) uniform simulationBlock {
Simulation simulation;
};
layout(location = 0) in vec2 vertexPos;
layout(location = 0) out vec2 passPos;
layout(location = 1) out vec3 passVelocity;
layout(location = 2) out float passMass;
......@@ -25,6 +23,12 @@ ivec3 actual_mod(ivec3 x, ivec3 y) {
}
void main() {
const vec2 positions[3] = {
vec2(-1.0f, -1.0f),
vec2(+0.0f, +1.5f),
vec2(+1.0f, -1.0f)
};
ivec3 gridResolution = textureSize(sampler3D(gridImage, gridSampler), 0);
ivec3 gridID = ivec3(
......@@ -48,11 +52,11 @@ void main() {
float alpha = clamp(density / simulation.density, 0.0f, 1.0f);
passPos = vertexPos;
passPos = positions[gl_VertexIndex];
passVelocity = gridData.xyz;
passMass = mass;
// align voxel to face camera
gl_Position = mvp * vec4(position, 1); // transform position into projected view space
gl_Position.xy += vertexPos * (radius * 2.0f) * alpha; // move position directly in view space
gl_Position.xy += positions[gl_VertexIndex] * (radius * 2.0f) * alpha; // move position directly in view space
}
\ No newline at end of file
#version 450
layout(location = 0) in vec3 vertexPos;
layout( push_constant ) uniform constants{
mat4 mvp;
};
void main() {
gl_Position = mvp * vec4(vertexPos, 1);
const vec3 positions[8] = {
vec3(0.0f, 0.0f, 0.0f),
vec3(1.0f, 0.0f, 0.0f),
vec3(0.0f, 1.0f, 0.0f),
vec3(1.0f, 1.0f, 0.0f),
vec3(0.0f, 0.0f, 1.0f),
vec3(1.0f, 0.0f, +1.0f),
vec3(0.0f, 1.0f, 1.0f),
vec3(1.0f, 1.0f, 1.0f)
};
gl_Position = mvp * vec4(positions[gl_VertexIndex], 1);
}
\ No newline at end of file
......@@ -7,8 +7,6 @@ layout(set=0, binding=0, std430) readonly buffer particleBuffer {
Particle particles [];
};
layout(location = 0) in vec2 vertexPos;
layout(location = 0) out vec2 passPos;
layout(location = 1) out float passMass;
......@@ -17,15 +15,21 @@ layout( push_constant ) uniform constants{
};
void main() {
const vec2 positions[3] = {
vec2(-1.0f, -1.0f),
vec2(+0.0f, +1.5f),
vec2(+1.0f, -1.0f)
};
vec3 position = particles[gl_InstanceIndex].minimal.position;
float size = particles[gl_InstanceIndex].minimal.size;
float mass = particles[gl_InstanceIndex].minimal.mass;
passPos = vertexPos;
passPos = positions[gl_VertexIndex];
passMass = mass;
// align particle to face camera
gl_Position = mvp * vec4(position, 1); // transform position into projected view space
gl_Position.xy += vertexPos * size * 2.0f; // move position directly in view space
gl_Position.xy += positions[gl_VertexIndex] * size * 2.0f; // move position directly in view space
}
\ No newline at end of file
......@@ -521,42 +521,27 @@ int main(int argc, const char **argv) {
vkcv::PassHandle gfxPassParticles = core.createPass(passConfigParticles);
vkcv::PassHandle gfxPassLines = core.createPass(passConfigLines);
vkcv::VertexLayout vertexLayoutGrid ({
vkcv::createVertexBinding(0, gfxProgramGrid.getVertexAttachments())
});
vkcv::GraphicsPipelineConfig gfxPipelineConfigGrid;
gfxPipelineConfigGrid.m_ShaderProgram = gfxProgramGrid;
gfxPipelineConfigGrid.m_Width = windowWidth;
gfxPipelineConfigGrid.m_Height = windowHeight;
gfxPipelineConfigGrid.m_PassHandle = gfxPassGrid;
gfxPipelineConfigGrid.m_VertexLayout = vertexLayoutGrid;
gfxPipelineConfigGrid.m_DescriptorLayouts = { gfxSetLayoutGrid };
gfxPipelineConfigGrid.m_UseDynamicViewport = true;
vkcv::VertexLayout vertexLayoutParticles ({
vkcv::createVertexBinding(0, gfxProgramParticles.getVertexAttachments())
});
vkcv::GraphicsPipelineConfig gfxPipelineConfigParticles;
gfxPipelineConfigParticles.m_ShaderProgram = gfxProgramParticles;
gfxPipelineConfigParticles.m_Width = windowWidth;
gfxPipelineConfigParticles.m_Height = windowHeight;
gfxPipelineConfigParticles.m_PassHandle = gfxPassParticles;
gfxPipelineConfigParticles.m_VertexLayout = vertexLayoutParticles;
gfxPipelineConfigParticles.m_DescriptorLayouts = { gfxSetLayoutParticles };
gfxPipelineConfigParticles.m_UseDynamicViewport = true;
vkcv::VertexLayout vertexLayoutLines ({
vkcv::createVertexBinding(0, gfxProgramLines.getVertexAttachments())
});
vkcv::GraphicsPipelineConfig gfxPipelineConfigLines;
gfxPipelineConfigLines.m_ShaderProgram = gfxProgramLines;
gfxPipelineConfigLines.m_Width = windowWidth;
gfxPipelineConfigLines.m_Height = windowHeight;
gfxPipelineConfigLines.m_PassHandle = gfxPassLines;
gfxPipelineConfigLines.m_VertexLayout = vertexLayoutLines;
gfxPipelineConfigLines.m_DescriptorLayouts = {};
gfxPipelineConfigLines.m_UseDynamicViewport = true;
gfxPipelineConfigLines.m_PrimitiveTopology = vkcv::PrimitiveTopology::LineList;
......@@ -565,36 +550,16 @@ int main(int argc, const char **argv) {
vkcv::GraphicsPipelineHandle gfxPipelineParticles = core.createGraphicsPipeline(gfxPipelineConfigParticles);
vkcv::GraphicsPipelineHandle gfxPipelineLines = core.createGraphicsPipeline(gfxPipelineConfigLines);
vkcv::Buffer<glm::vec2> trianglePositions = core.createBuffer<glm::vec2>(vkcv::BufferType::VERTEX, 3);
trianglePositions.fill({
glm::vec2(-1.0f, -1.0f),
glm::vec2(+0.0f, +1.5f),
glm::vec2(+1.0f, -1.0f)
});
vkcv::Buffer<uint16_t> triangleIndices = core.createBuffer<uint16_t>(vkcv::BufferType::INDEX, 3);
triangleIndices.fill({
0, 1, 2
});
vkcv::Mesh triangleMesh (
{ vkcv::VertexBufferBinding(0, trianglePositions.getVulkanHandle()) },
triangleIndices.getVulkanHandle(),
triangleIndices.getCount()
);
vkcv::Buffer<glm::vec3> linesPositions = core.createBuffer<glm::vec3>(vkcv::BufferType::VERTEX, 8);
linesPositions.fill({
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(1.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f),
glm::vec3(1.0f, 1.0f, 0.0f),
glm::vec3(0.0f, 0.0f, 1.0f),
glm::vec3(1.0f, 0.0f, +1.0f),
glm::vec3(0.0f, 1.0f, 1.0f),
glm::vec3(1.0f, 1.0f, 1.0f)
});
vkcv::Buffer<uint16_t> linesIndices = core.createBuffer<uint16_t>(vkcv::BufferType::INDEX, 24);
linesIndices.fill({
0, 1,
......@@ -614,7 +579,6 @@ int main(int argc, const char **argv) {
});
vkcv::Mesh linesMesh (
{ vkcv::VertexBufferBinding(0, linesPositions.getVulkanHandle()) },
linesIndices.getVulkanHandle(),
linesIndices.getCount()
);
......@@ -832,9 +796,9 @@ int main(int argc, const char **argv) {
ImGui::Begin("Settings");
ImGui::BeginGroup();
ImGui::Combo("Mode", &(sim->mode), "Random\0Ordered", 2);
ImGui::Combo("Form", &(sim->form), "Sphere\0Cube", 2);
ImGui::Combo("Type", &(sim->type), "Hyperelastic\0Fluid", 2);
ImGui::Combo("Mode", &(sim->mode), "Random\0Ordered\0", 2);
ImGui::Combo("Form", &(sim->form), "Sphere\0Cube\0", 2);
ImGui::Combo("Type", &(sim->type), "Hyperelastic\0Fluid\0", 2);
ImGui::EndGroup();
ImGui::Spacing();
......
......@@ -293,11 +293,6 @@ namespace vkcv
const PushConstants &pushConstants,
const size_t drawcallIndex) {
for (uint32_t i = 0; i < drawcall.mesh.vertexBufferBindings.size(); i++) {
const auto& vertexBinding = drawcall.mesh.vertexBufferBindings[i];
cmdBuffer.bindVertexBuffers(i, vertexBinding.buffer, vertexBinding.offset);
}
for (const auto& descriptorUsage : drawcall.descriptorSets) {
cmdBuffer.bindDescriptorSets(
vk::PipelineBindPoint::eGraphics,
......@@ -470,8 +465,6 @@ namespace vkcv
descSet.vulkanHandle,
nullptr);
vk::DeviceSize deviceSize = 0;
cmdBuffer.bindVertexBuffers(0, 1, &compiledMesh.vertexBufferBindings[0].buffer,&deviceSize);
cmdBuffer.bindIndexBuffer(compiledMesh.indexBuffer, 0, getIndexType(compiledMesh.indexBitCount));
cmdBuffer.drawIndexedIndirect(
......
......@@ -18,31 +18,6 @@ namespace vkcv
}
}
// currently assuming default 32 bit formats, no lower precision or normalized variants supported
vk::Format vertexFormatToVulkanFormat(const VertexAttachmentFormat format) {
switch (format) {
case VertexAttachmentFormat::FLOAT:
return vk::Format::eR32Sfloat;
case VertexAttachmentFormat::FLOAT2:
return vk::Format::eR32G32Sfloat;
case VertexAttachmentFormat::FLOAT3:
return vk::Format::eR32G32B32Sfloat;
case VertexAttachmentFormat::FLOAT4:
return vk::Format::eR32G32B32A32Sfloat;
case VertexAttachmentFormat::INT:
return vk::Format::eR32Sint;
case VertexAttachmentFormat::INT2:
return vk::Format::eR32G32Sint;
case VertexAttachmentFormat::INT3:
return vk::Format::eR32G32B32Sint;
case VertexAttachmentFormat::INT4:
return vk::Format::eR32G32B32A32Sint;
default:
vkcv_log(LogLevel::WARNING, "Unknown vertex format");
return vk::Format::eUndefined;
}
}
vk::PrimitiveTopology primitiveTopologyToVulkanPrimitiveTopology(const PrimitiveTopology topology) {
switch (topology) {
case(PrimitiveTopology::PointList):
......@@ -128,56 +103,17 @@ namespace vkcv
}
/**
* Fills Vertex Attribute and Binding Description with the corresponding objects form the Vertex Layout.
* @param vertexAttributeDescriptions
* @param vertexBindingDescriptions
* @param existsVertexShader
* @param config
*/
void fillVertexInputDescription(
std::vector<vk::VertexInputAttributeDescription> &vertexAttributeDescriptions,
std::vector<vk::VertexInputBindingDescription> &vertexBindingDescriptions,
const bool existsVertexShader,
const GraphicsPipelineConfig &config) {
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);
}
}
}
}
/**
* Creates a Pipeline Vertex Input State Create Info Struct and fills it with Attribute and Binding data.
* @param vertexAttributeDescriptions
* @param vertexBindingDescriptions
* Creates a Pipeline Vertex Input State Create Info Struct.
* @return Pipeline Vertex Input State Create Info Struct
*/
vk::PipelineVertexInputStateCreateInfo createPipelineVertexInputStateCreateInfo(
std::vector<vk::VertexInputAttributeDescription> &vertexAttributeDescriptions,
std::vector<vk::VertexInputBindingDescription> &vertexBindingDescriptions) {
vk::PipelineVertexInputStateCreateInfo createPipelineVertexInputStateCreateInfo() {
vk::PipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo(
{},
vertexBindingDescriptions.size(),
vertexBindingDescriptions.data(),
vertexAttributeDescriptions.size(),
vertexAttributeDescriptions.data()
0,
nullptr,
0,
nullptr
);
return pipelineVertexInputStateCreateInfo;
}
......@@ -587,16 +523,9 @@ namespace vkcv
}
}
// vertex input state
// Fill up VertexInputBindingDescription and VertexInputAttributeDescription Containers
std::vector<vk::VertexInputAttributeDescription> vertexAttributeDescriptions;
std::vector<vk::VertexInputBindingDescription> vertexBindingDescriptions;
fillVertexInputDescription(vertexAttributeDescriptions, vertexBindingDescriptions, existsVertexShader, config);
// Handover Containers to PipelineVertexInputStateCreateIngo Struct
vk::PipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo =
createPipelineVertexInputStateCreateInfo(vertexAttributeDescriptions,
vertexBindingDescriptions);
createPipelineVertexInputStateCreateInfo();
// input assembly state
vk::PipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo =
......
......@@ -38,47 +38,8 @@ namespace vkcv {
return buffer;
}
VertexAttachmentFormat convertFormat(spirv_cross::SPIRType::BaseType basetype, uint32_t vecsize){
switch (basetype) {
case spirv_cross::SPIRType::Int:
switch (vecsize) {
case 1:
return VertexAttachmentFormat::INT;
case 2:
return VertexAttachmentFormat::INT2;
case 3:
return VertexAttachmentFormat::INT3;
case 4:
return VertexAttachmentFormat::INT4;
default:
break;
}
break;
case spirv_cross::SPIRType::Float:
switch (vecsize) {
case 1:
return VertexAttachmentFormat::FLOAT;
case 2:
return VertexAttachmentFormat::FLOAT2;
case 3:
return VertexAttachmentFormat::FLOAT3;
case 4:
return VertexAttachmentFormat::FLOAT4;
default:
break;
}
break;
default:
break;
}
vkcv_log(LogLevel::WARNING, "Unknown vertex format");
return VertexAttachmentFormat::FLOAT;
}
ShaderProgram::ShaderProgram() noexcept :
m_Shaders{},
m_VertexAttachments{},
m_DescriptorSets{}
{}
......@@ -122,27 +83,9 @@ namespace vkcv {
//reflect vertex input
if (shaderStage == ShaderStage::VERTEX)
{
// spirv-cross API (hopefully) returns the stage_inputs in order
for (uint32_t i = 0; i < resources.stage_inputs.size(); i++)
{
// spirv-cross specific objects
auto& stage_input = resources.stage_inputs[i];
const spirv_cross::SPIRType& base_type = comp.get_type(stage_input.base_type_id);
// vertex input location
const uint32_t attachment_loc = comp.get_decoration(stage_input.id, spv::DecorationLocation);
// vertex input name
const std::string attachment_name = stage_input.name;
// vertex input format (implies its size)
const VertexAttachmentFormat attachment_format = convertFormat(base_type.basetype, base_type.vecsize);
m_VertexAttachments.push_back({
attachment_loc,
attachment_name,
attachment_format,
0
});
}
if (!resources.stage_inputs.empty()) {
vkcv_log(LogLevel::WARNING, "Vertex bindings are not supported");
}
}
//reflect descriptor sets (uniform buffer, storage buffer, sampler, sampled image, storage image)
......@@ -372,11 +315,6 @@ namespace vkcv {
}
}
const VertexAttachments &ShaderProgram::getVertexAttachments() const
{
return m_VertexAttachments;
}
const std::unordered_map<uint32_t, DescriptorBindings>& ShaderProgram::getReflectedDescriptors() const
{
return m_DescriptorSets;
......
//
// Created by Charlotte on 28.05.2021.
//
#include "vkcv/VertexLayout.hpp"
#include "vkcv/Logger.hpp"
namespace vkcv {
uint32_t getFormatSize(VertexAttachmentFormat format) {
switch (format) {
case VertexAttachmentFormat::FLOAT:
return 4;
case VertexAttachmentFormat::FLOAT2:
return 8;
case VertexAttachmentFormat::FLOAT3:
return 12;
case VertexAttachmentFormat::FLOAT4:
return 16;
case VertexAttachmentFormat::INT:
return 4;
case VertexAttachmentFormat::INT2:
return 8;
case VertexAttachmentFormat::INT3:
return 12;
case VertexAttachmentFormat::INT4:
return 16;
default:
vkcv_log(LogLevel::WARNING, "No format given");
return 0;
}
}
VertexBinding createVertexBinding(uint32_t bindingLocation, const VertexAttachments &attachments) {
VertexBinding binding { bindingLocation, 0, attachments };
uint32_t offset = 0;
for (auto& attachment : binding.vertexAttachments) {
attachment.offset = offset;
offset += getFormatSize(attachment.format);
}
binding.stride = offset;
return binding;
}
}
\ No newline at end of file