More Refactoring

This commit is contained in:
Dynamitos
2023-11-15 17:42:57 +01:00
parent f8f48352a3
commit 35966cb5b7
60 changed files with 1217 additions and 2332 deletions
+58 -7
View File
@@ -1,10 +1,5 @@
import Common;
struct VertexShaderInput
{
float3 position;
};
struct VertexShaderOutput
{
float4 clipPos : SV_Position;
@@ -18,13 +13,69 @@ struct SkyboxData
layout(set=1)
ParameterBlock<SkyboxData> pSkyboxData;
float3 vertices[] = {
// Back
float3(-512, -512, 512),
float3(-512, 512, 512),
float3( 512, -512, 512),
float3( 512, -512, 512),
float3(-512, 512, 512),
float3( 512, 512, 512),
// Front
float3( 512, -512, -512),
float3( 512, 512, -512),
float3(-512, -512, -512),
float3(-512, -512, -512),
float3( 512, 512, -512),
float3(-512, 512, -512),
// Top
float3(-512, -512, -512),
float3(-512, -512, 512),
float3( 512, -512, -512),
float3( 512, -512, -512),
float3(-512, -512, 512),
float3( 512, -512, 512),
// Bottom
float3(-512, 512, 512),
float3(-512, 512, -512),
float3( 512, 512, 512),
float3( 512, 512, 512),
float3(-512, 512, -512),
float3( 512, 512, -512),
// Left
float3(-512, -512, -512),
float3(-512, 512, -512),
float3(-512, -512, 512),
float3(-512, -512, 512),
float3(-512, 512, -512),
float3(-512, 512, 512),
// Right
float3( 512, -512, 512),
float3( 512, 512, 512),
float3( 512, -512, -512),
float3( 512, -512, -512),
float3( 512, 512, 512),
float3( 512, 512, -512),
};
[shader("vertex")]
VertexShaderOutput vertexMain(
VertexShaderInput input)
uint vertexIndex : SV_VertexId)
{
VertexShaderOutput output;
float3x3 cameraRotation = float3x3(pViewParams.viewMatrix);
float4 worldPos = float4(mul(cameraRotation, input.position), 1.0f);
float4 worldPos = float4(mul(cameraRotation, vertices[vertexIndex]), 1.0f);
//clip(dot(worldPos, clipPlane));
output.clipPos = mul(pViewParams.projectionMatrix, worldPos);
output.texCoords = normalize(input.position);
+17 -8
View File
@@ -13,15 +13,24 @@ ParameterBlock<SamplerState> glyphSampler;
//layout(set = 1)
//ShaderBuffer<GlyphData> glyphData;
ParameterBuffer<Texture2D<uint>[]> pGlyphTextures;
[[vk::push_constant]]
ConstantBuffer<TextData> textData;
struct VertexInput
struct GlyphInstanceData
{
float2 position;
float2 widthHeight;
uint glyphIndex;
};
struct TextRender
{
StructuredBuffer<GlyphInstanceData> instances;
TextData textData;
}
ParameterBuffer<TextRender> pRender;
struct VertexInput
{
uint vertexId : SV_VertexID;
uint instanceId : SV_InstanceID;
};
struct VertexOutput
@@ -34,11 +43,11 @@ struct VertexOutput
[shader("vertex")]
VertexOutput vertexMain(VertexInput input)
{
float xpos = input.position.x;
float ypos = input.position.y;
float xpos = pRender.instances[input.instanceId].position.x;
float ypos = pRender.instances[input.instanceId].position.y;
float w = input.widthHeight.x;
float h = input.widthHeight.y;
float w = pRender.instances[input.instanceId].widthHeight.x;
float h = pRender.instances[input.instanceId].widthHeight.y;
float4 coordinates[4] = {
float4(xpos, ypos, 0, 1),
@@ -50,7 +59,7 @@ VertexOutput vertexMain(VertexInput input)
VertexStageOutput output;
output.texCoords = vertex.zw;
output.position = mul(viewData.projectionMatrix, float4(vertex.xy, 0, 1));
output.glyphIndex = input.glyphIndex;
output.glyphIndex = pRender.instances[input.instanceId].glyphIndex;
return output;
}
+3 -2
View File
@@ -1,5 +1,6 @@
#include "MaterialLoader.h"
#include "Graphics/Graphics.h"
#include "Graphics/Shader.h"
#include "Asset/MaterialAsset.h"
#include "Asset/AssetRegistry.h"
#include "Material/Material.h"
@@ -109,11 +110,11 @@ void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset)
parameters.add(p->key);
expressions.add(std::move(p));
}
else if(type.compare("SamplerState") == 0)
else if(type.compare("Sampler") == 0)
{
OSamplerParameter p = new SamplerParameter(param.key(), 0, bindingCounter);
layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER);
p->data = graphics->createSamplerState({});
p->data = graphics->createSampler({});
parameters.add(p->key);
expressions.add(std::move(p));
}
+1
View File
@@ -107,6 +107,7 @@ AssetRegistry &AssetRegistry::get()
}
AssetRegistry::AssetRegistry()
: assetRoot(nullptr)
{
}
+3 -3
View File
@@ -100,13 +100,13 @@ void FontAsset::load(ArchiveBuffer& buffer)
.data = ktxTexture_GetData(ktxTexture(kTexture)),
.owner = Gfx::QueueType::GRAPHICS,
},
.format = Vulkan::cast((VkFormat)kTexture->vkFormat),
.width = kTexture->baseWidth,
.height = kTexture->baseHeight,
.depth = kTexture->baseDepth,
.bArray = kTexture->isArray,
.arrayLayers = kTexture->isArray ? kTexture->numLayers : kTexture->numFaces,
.mipLevels = kTexture->numLevels,
.format = Vulkan::cast((VkFormat)kTexture->vkFormat),
.layers = kTexture->numFaces,
.elements = kTexture->numLayers,
.usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
};
+3 -3
View File
@@ -91,13 +91,13 @@ void TextureAsset::load(ArchiveBuffer& buffer)
.data = ktxTexture_GetData(ktxTexture(kTexture)),
.owner = Gfx::QueueType::DEDICATED_TRANSFER,
},
.format = Vulkan::cast((VkFormat)kTexture->vkFormat),
.width = kTexture->baseWidth,
.height = kTexture->baseHeight,
.depth = kTexture->baseDepth,
.bArray = kTexture->isArray,
.arrayLayers = kTexture->isArray ? kTexture->numLayers : kTexture->numFaces,
.mipLevels = kTexture->numLevels,
.format = Vulkan::cast((VkFormat)kTexture->vkFormat),
.layers = kTexture->numFaces,
.elements = kTexture->numLayers,
.usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
};
if (kTexture->isCubemap)
+1
View File
@@ -1,5 +1,6 @@
#pragma once
#include "Enums.h"
#include "Descriptor.h"
namespace Seele
{
+4 -4
View File
@@ -31,11 +31,11 @@ DescriptorBinding& DescriptorBinding::operator=(const DescriptorBinding& other)
return *this;
}
DescriptorAllocator::DescriptorAllocator()
DescriptorPool::DescriptorPool()
{
}
DescriptorAllocator::~DescriptorAllocator()
DescriptorPool::~DescriptorPool()
{
}
@@ -87,12 +87,12 @@ void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorTyp
PDescriptorSet DescriptorLayout::allocateDescriptorSet()
{
return allocator->allocateDescriptorSet();
return pool->allocateDescriptorSet();
}
void DescriptorLayout::reset()
{
allocator->reset();
pool->reset();
}
PipelineLayout::PipelineLayout()
+8 -7
View File
@@ -21,15 +21,15 @@ public:
DEFINE_REF(DescriptorBinding)
DECLARE_REF(DescriptorSet)
class DescriptorAllocator
class DescriptorPool
{
public:
DescriptorAllocator();
virtual ~DescriptorAllocator();
DescriptorPool();
virtual ~DescriptorPool();
virtual PDescriptorSet allocateDescriptorSet() = 0;
virtual void reset() = 0;
};
DEFINE_REF(DescriptorAllocator)
DEFINE_REF(DescriptorPool)
DECLARE_REF(UniformBuffer)
DECLARE_REF(ShaderBuffer)
DECLARE_REF(Texture)
@@ -68,11 +68,11 @@ public:
protected:
Array<DescriptorBinding> descriptorBindings;
ODescriptorAllocator allocator;
ODescriptorPool pool;
uint32 setIndex;
std::string name;
friend class PipelineLayout;
friend class DescriptorAllocator;
friend class DescriptorPool;
};
DEFINE_REF(DescriptorLayout)
class PipelineLayout
@@ -85,9 +85,10 @@ public:
virtual void reset() = 0;
void addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout);
void addPushConstants(const SePushConstantRange& pushConstants);
virtual uint32 getHash() const = 0;
constexpr uint32 getHash() const { return layoutHash; }
protected:
uint32 layoutHash;
Array<PDescriptorLayout> descriptorSetLayouts;
Array<SePushConstantRange> pushConstants;
};
+3 -1
View File
@@ -29,6 +29,8 @@ DECLARE_REF(UniformBuffer)
DECLARE_REF(PipelineLayout)
DECLARE_REF(GraphicsPipeline)
DECLARE_REF(ComputePipeline)
DECLARE_REF(RenderCommand)
DECLARE_REF(ComputeCommand)
class Graphics
{
public:
@@ -75,7 +77,7 @@ public:
virtual PGraphicsPipeline createGraphicsPipeline(LegacyPipelineCreateInfo createInfo) = 0;
virtual PGraphicsPipeline createGraphicsPipeline(MeshPipelineCreateInfo createInfo) = 0;
virtual PComputePipeline createComputePipeline(ComputePipelineCreateInfo createInfo) = 0;
virtual OSampler createSamplerState(const SamplerCreateInfo& createInfo) = 0;
virtual OSampler createSampler(const SamplerCreateInfo& createInfo) = 0;
virtual ODescriptorLayout createDescriptorLayout(const std::string& name = "") = 0;
virtual OPipelineLayout createPipelineLayout(PPipelineLayout baseLayout = nullptr) = 0;
+2 -2
View File
@@ -17,8 +17,8 @@ LegacyPipelineCreateInfo::LegacyPipelineCreateInfo()
, depthStencilState(DepthStencilState{
.depthTestEnable = true,
.depthWriteEnable = true,
.stencilTestEnable = false,
.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL,
.stencilTestEnable = false,
.minDepthBounds = 0.0f,
.maxDepthBounds = 1.0f,
})
@@ -61,8 +61,8 @@ MeshPipelineCreateInfo::MeshPipelineCreateInfo()
, depthStencilState(DepthStencilState{
.depthTestEnable = true,
.depthWriteEnable = true,
.stencilTestEnable = false,
.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL,
.stencilTestEnable = false,
.minDepthBounds = 0.0f,
.maxDepthBounds = 1.0f,
})
+3 -1
View File
@@ -62,7 +62,8 @@ struct TextureCreateInfo
uint32 height = 1;
uint32 depth = 1;
uint32 mipLevels = 1;
uint32 arrayLayers = 1;
uint32 layers = 1;
uint32 elements = 1;
uint32 samples = 1;
Gfx::SeImageUsageFlagBits usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT;
};
@@ -105,6 +106,7 @@ struct UniformBufferCreateInfo
struct ShaderBufferCreateInfo
{
DataSource sourceData = DataSource();
uint64 numElements = 1;
uint8 dynamic = 0;
};
struct ShaderCreateInfo
+1 -1
View File
@@ -4,7 +4,7 @@ using namespace Seele;
using namespace Seele::Gfx;
GraphicsPipeline::GraphicsPipeline(OPipelineLayout layout)
: layout(std::move(layout)) {}
: layout(std::move(layout))
{
}
+1 -1
View File
@@ -11,6 +11,7 @@
#include "RenderGraph.h"
#include "Material/MaterialInstance.h"
#include "Graphics/Descriptor.h"
#include "Graphics/Command.h"
using namespace Seele;
@@ -128,7 +129,6 @@ void BasePass::render()
else
{
Gfx::LegacyPipelineCreateInfo pipelineInfo;
pipelineInfo.vertexDeclaration = collection->vertexDeclaration;
pipelineInfo.vertexShader = collection->vertexShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = std::move(layout);
@@ -8,6 +8,7 @@
#include "Actor/CameraActor.h"
#include "Math/Vector.h"
#include "RenderGraph.h"
#include "Graphics/Command.h"
using namespace Seele;
@@ -89,7 +90,6 @@ void DepthPrepass::render()
else
{
Gfx::LegacyPipelineCreateInfo pipelineInfo;
pipelineInfo.vertexDeclaration = collection->vertexDeclaration;
pipelineInfo.vertexShader = collection->vertexShader;
pipelineInfo.fragmentShader = collection->fragmentShader;
pipelineInfo.pipelineLayout = std::move(layout);
@@ -141,13 +141,14 @@ void DepthPrepass::endFrame()
void DepthPrepass::publishOutputs()
{
TextureCreateInfo depthBufferInfo;
// If we render to a part of an image, the depth buffer itself must
// still match the size of the whole image or their coordinate systems go out of sync
depthBufferInfo.width = viewport->getOwner()->getWidth();
depthBufferInfo.height = viewport->getOwner()->getHeight();
depthBufferInfo.format = Gfx::SE_FORMAT_D32_SFLOAT;
depthBufferInfo.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
TextureCreateInfo depthBufferInfo = {
.format = Gfx::SE_FORMAT_D32_SFLOAT,
.width = viewport->getOwner()->getWidth(),
.height = viewport->getOwner()->getHeight(),
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
};
depthBuffer = graphics->createTexture2D(depthBufferInfo);
depthAttachment =
new Gfx::RenderTargetAttachment(depthBuffer, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
@@ -4,6 +4,7 @@
#include "Actor/CameraActor.h"
#include "Component/Camera.h"
#include "RenderGraph.h"
#include "Graphics/Command.h"
using namespace Seele;
@@ -130,14 +131,13 @@ void LightCullingPass::publishOutputs()
cullingPipeline = graphics->createComputePipeline(std::move(pipelineInfo));
uint32 counterReset = 0;
ShaderBufferCreateInfo structInfo =
{
ShaderBufferCreateInfo structInfo = {
.sourceData = {
.size = sizeof(uint32),
.data = (uint8*)&counterReset,
.owner = Gfx::QueueType::COMPUTE,
},
.stride = sizeof(uint32),
.numElements = 1,
.dynamic = true,
};
oLightIndexCounter = graphics->createShaderBuffer(structInfo);
@@ -151,7 +151,6 @@ void LightCullingPass::publishOutputs()
.data = nullptr,
.owner = Gfx::QueueType::COMPUTE
},
.stride = sizeof(uint32),
.dynamic = false,
};
oLightIndexList = graphics->createShaderBuffer(structInfo);
@@ -160,9 +159,9 @@ void LightCullingPass::publishOutputs()
resources->registerBufferOutput("LIGHTCULLING_TLIGHTLIST", tLightIndexList);
TextureCreateInfo textureInfo = {
.format = Gfx::SE_FORMAT_R32G32_UINT,
.width = dispatchParams.numThreadGroups.x,
.height = dispatchParams.numThreadGroups.y,
.format = Gfx::SE_FORMAT_R32G32_UINT,
.usage = Gfx::SE_IMAGE_USAGE_STORAGE_BIT,
};
oLightGrid = graphics->createTexture2D(textureInfo);
@@ -226,7 +225,7 @@ void LightCullingPass::setupFrustums()
.size = sizeof(Frustum) * numThreads.x * numThreads.y * numThreads.z,
.data = nullptr,
},
.stride = sizeof(Frustum),
.numElements = numThreads.x * numThreads.y * numThreads.z,
.dynamic = false,
});
@@ -1,6 +1,6 @@
#pragma once
#include "RenderPass.h"
#include "Graphics/Resources.h"
#include "Graphics/Shader.h"
#include "Scene/Scene.h"
namespace Seele
@@ -1,6 +1,7 @@
#include "SkyboxRenderPass.h"
#include "Graphics/Graphics.h"
#include "Asset/AssetRegistry.h"
#include "Graphics/Command.h"
using namespace Seele;
@@ -13,71 +14,6 @@ SkyboxRenderPass::SkyboxRenderPass(Gfx::PGraphics graphics, PScene scene)
.fogColor = Vector(0.2, 0.1, 0.6),
.blendFactor = 0,
};
Array<Vector> vertices = {
// Back
Vector(-512, -512, 512),
Vector(-512, 512, 512),
Vector( 512, -512, 512),
Vector( 512, -512, 512),
Vector(-512, 512, 512),
Vector( 512, 512, 512),
// Front
Vector( 512, -512, -512),
Vector( 512, 512, -512),
Vector(-512, -512, -512),
Vector(-512, -512, -512),
Vector( 512, 512, -512),
Vector(-512, 512, -512),
// Top
Vector(-512, -512, -512),
Vector(-512, -512, 512),
Vector( 512, -512, -512),
Vector( 512, -512, -512),
Vector(-512, -512, 512),
Vector( 512, -512, 512),
// Bottom
Vector(-512, 512, 512),
Vector(-512, 512, -512),
Vector( 512, 512, 512),
Vector( 512, 512, 512),
Vector(-512, 512, -512),
Vector( 512, 512, -512),
// Left
Vector(-512, -512, -512),
Vector(-512, 512, -512),
Vector(-512, -512, 512),
Vector(-512, -512, 512),
Vector(-512, 512, -512),
Vector(-512, 512, 512),
// Right
Vector( 512, -512, 512),
Vector( 512, 512, 512),
Vector( 512, -512, -512),
Vector( 512, -512, -512),
Vector( 512, 512, 512),
Vector( 512, 512, -512),
};
VertexBufferCreateInfo vertexBufferInfo = {
.sourceData = {
.size = sizeof(Vector) * vertices.size(),
.data = (uint8*)vertices.data(),
},
.vertexSize = sizeof(Vector),
.numVertices = (uint32)vertices.size(),
};
cubeBuffer = graphics->createVertexBuffer(vertexBufferInfo);
}
SkyboxRenderPass::~SkyboxRenderPass()
{
@@ -146,7 +82,7 @@ void SkyboxRenderPass::publishOutputs()
textureLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER);
textureLayout->create();
skyboxSampler = graphics->createSamplerState({});
skyboxSampler = graphics->createSampler({});
}
void SkyboxRenderPass::createRenderPass()
@@ -169,16 +105,6 @@ void SkyboxRenderPass::createRenderPass()
createInfo.entryPoint = "fragmentMain";
fragmentShader = graphics->createFragmentShader(createInfo);
declaration = graphics->createVertexDeclaration({
Gfx::VertexElement {
.binding = 0,
.offset = 0,
.vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
.attributeIndex = 0,
.stride = sizeof(Vector),
}
});
Gfx::OPipelineLayout pipelineLayout = graphics->createPipelineLayout();
pipelineLayout->addDescriptorLayout(0, viewParamsLayout);
pipelineLayout->addDescriptorLayout(1, skyboxDataLayout);
@@ -186,7 +112,6 @@ void SkyboxRenderPass::createRenderPass()
pipelineLayout->create();
Gfx::LegacyPipelineCreateInfo gfxInfo;
gfxInfo.vertexDeclaration = declaration;
gfxInfo.vertexShader = vertexShader;
gfxInfo.fragmentShader = fragmentShader;
gfxInfo.rasterizationState.polygonMode = Gfx::SE_POLYGON_MODE_FILL;
@@ -1,13 +1,10 @@
#pragma once
#include "RenderPass.h"
#include "Graphics/Resources.h"
#include "Graphics/Shader.h"
#include "Component/Skybox.h"
namespace Seele
{
DECLARE_REF(CameraActor)
DECLARE_REF(Scene)
DECLARE_REF(Viewport)
class SkyboxRenderPass : public RenderPass
{
public:
@@ -27,11 +24,10 @@ private:
Gfx::PDescriptorSet skyboxDataSet;
Gfx::ODescriptorLayout textureLayout;
Gfx::PDescriptorSet textureSet;
Gfx::OVertexDeclaration declaration;
Gfx::OVertexShader vertexShader;
Gfx::OFragmentShader fragmentShader;
Gfx::PGraphicsPipeline pipeline;
Gfx::OSamplerState skyboxSampler;
Gfx::OSampler skyboxSampler;
Component::Skybox skybox;
};
DEFINE_REF(SkyboxRenderPass)
+8 -37
View File
@@ -2,6 +2,7 @@
#include "RenderGraph.h"
#include "Graphics/Graphics.h"
#include "Graphics/RenderTarget.h"
#include "Graphics/Command.h"
using namespace Seele;
@@ -43,15 +44,13 @@ void TextPass::beginFrame(const Component::Camera& cam)
});
x += (glyph.advance >> 6) * render.scale;
}
VertexBufferCreateInfo vbInfo = {
res.instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData = {
.size = static_cast<uint32>(instanceData.size() * sizeof(GlyphInstanceData)),
.data = reinterpret_cast<uint8*>(instanceData.data()),
},
.vertexSize = sizeof(GlyphInstanceData),
.numVertices = static_cast<uint32>(instanceData.size()),
};
res.vertexBuffer = graphics->createVertexBuffer(vbInfo);
},
.numElements = instanceData.size(),
});
res.textureArraySet = fd.textureArraySet;
@@ -83,10 +82,10 @@ void TextPass::render()
for(const auto& resource : res)
{
command->bindDescriptor({generalSet, resource.textureArraySet});
command->bindVertexBuffer({resource.vertexBuffer});
//command->bindVertexBuffer({resource.vertexBuffer});
command->pushConstants(layoutRef, Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(TextData), &resource.textData);
command->draw(4, static_cast<uint32>(resource.vertexBuffer->getNumVertices()), 0, 0);
//command->draw(4, static_cast<uint32>(resource.vertexBuffer->getNumVertices()), 0, 0);
}
commands.add(command);
}
@@ -120,33 +119,6 @@ void TextPass::createRenderPass()
createInfo.name = "TextFragment";
createInfo.entryPoint = "fragmentMain";
fragmentShader = graphics->createFragmentShader(createInfo);
Array<Gfx::VertexElement> elements;
elements.add({
.binding = 0,
.offset = offsetof(GlyphInstanceData, position),
.vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT,
.attributeIndex = 0,
.stride = sizeof(GlyphInstanceData),
.instanced = 1
});
elements.add({
.binding = 0,
.offset = offsetof(GlyphInstanceData, widthHeight),
.vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT,
.attributeIndex = 1,
.stride = sizeof(GlyphInstanceData),
.instanced = 1
});
elements.add({
.binding = 0,
.offset = offsetof(GlyphInstanceData, glyphIndex),
.vertexFormat = Gfx::SE_FORMAT_R32_UINT,
.attributeIndex = 2,
.stride = sizeof(GlyphInstanceData),
.instanced = 1
});
declaration = graphics->createVertexDeclaration(elements);
generalLayout = graphics->createDescriptorLayout("TextGeneral");
generalLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
generalLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER);
@@ -164,7 +136,7 @@ void TextPass::createRenderPass()
.dynamic = true,
});
glyphSampler = graphics->createSamplerState({
glyphSampler = graphics->createSampler({
.magFilter = Gfx::SE_FILTER_LINEAR,
.minFilter = Gfx::SE_FILTER_LINEAR,
.addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
@@ -190,7 +162,6 @@ void TextPass::createRenderPass()
renderPass = graphics->createRenderPass(std::move(layout), viewport);
Gfx::LegacyPipelineCreateInfo pipelineInfo;
pipelineInfo.vertexDeclaration = declaration;
pipelineInfo.vertexShader = vertexShader;
pipelineInfo.fragmentShader = fragmentShader;
pipelineInfo.renderPass = renderPass;
+3 -4
View File
@@ -1,8 +1,8 @@
#pragma once
#include "RenderPass.h"
#include "UI/RenderHierarchy.h"
#include "Graphics/Resources.h"
#include "Asset/FontAsset.h"
#include "Graphics/Shader.h"
namespace Seele
{
@@ -58,7 +58,7 @@ private:
struct TextResources
{
Gfx::PVertexBuffer vertexBuffer;
Gfx::PShaderBuffer instanceBuffer;
Gfx::PDescriptorSet textureArraySet;
TextData textData;
};
@@ -73,9 +73,8 @@ private:
Gfx::PDescriptorSet generalSet;
Gfx::OUniformBuffer projectionBuffer;
Gfx::OSamplerState glyphSampler;
Gfx::OSampler glyphSampler;
Gfx::OVertexDeclaration declaration;
Gfx::OVertexShader vertexShader;
Gfx::OFragmentShader fragmentShader;
Gfx::PPipelineLayout layoutRef;
+4 -46
View File
@@ -2,6 +2,7 @@
#include "RenderGraph.h"
#include "Graphics/Graphics.h"
#include "Graphics/RenderTarget.h"
#include "Graphics/Command.h"
using namespace Seele;
@@ -61,9 +62,9 @@ void UIPass::endFrame()
void UIPass::publishOutputs()
{
TextureCreateInfo depthBufferInfo = {
.format = Gfx::SE_FORMAT_D32_SFLOAT,
.width = viewport->getWidth(),
.height = viewport->getHeight(),
.format = Gfx::SE_FORMAT_D32_SFLOAT,
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
};
@@ -74,9 +75,9 @@ void UIPass::publishOutputs()
resources->registerRenderPassOutput("UIPASS_DEPTH", depthAttachment);
TextureCreateInfo colorBufferInfo = {
.format = Gfx::SE_FORMAT_R16G16B16A16_SFLOAT,
.width = viewport->getWidth(),
.height = viewport->getHeight(),
.format = Gfx::SE_FORMAT_R16G16B16A16_SFLOAT,
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
};
colorBuffer = graphics->createTexture2D(colorBufferInfo);
@@ -97,48 +98,6 @@ void UIPass::createRenderPass()
createInfo.name = "UIFragment";
createInfo.entryPoint = "fragmentMain";
fragmentShader = graphics->createFragmentShader(createInfo);
Array<Gfx::VertexElement> decl;
decl.add({
.binding = 0,
.offset = offsetof(UI::RenderElementStyle, position),
.vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
.attributeIndex = 0,
.stride = sizeof(UI::RenderElementStyle),
.instanced = 1
});
decl.add({
.binding = 0,
.offset = offsetof(UI::RenderElementStyle, backgroundImageIndex),
.vertexFormat = Gfx::SE_FORMAT_R32_UINT,
.attributeIndex = 1,
.stride = sizeof(UI::RenderElementStyle),
.instanced = 1
});
decl.add({
.binding = 0,
.offset = offsetof(UI::RenderElementStyle, backgroundColor),
.vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
.attributeIndex = 2,
.stride = sizeof(UI::RenderElementStyle),
.instanced = 1
});
decl.add({
.binding = 0,
.offset = offsetof(UI::RenderElementStyle, opacity),
.vertexFormat = Gfx::SE_FORMAT_R32_SFLOAT,
.attributeIndex = 3,
.stride = sizeof(UI::RenderElementStyle),
.instanced = 1
});
decl.add({
.binding = 0,
.offset = offsetof(UI::RenderElementStyle, dimensions),
.vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT,
.attributeIndex = 4,
.stride = sizeof(UI::RenderElementStyle),
.instanced = 1
});
declaration = graphics->createVertexDeclaration(decl);
descriptorLayout = graphics->createDescriptorLayout("UIDescriptorLayout");
descriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
@@ -156,7 +115,7 @@ void UIPass::createRenderPass()
.dynamic = false,
};
Gfx::OUniformBuffer uniformBuffer = graphics->createUniformBuffer(info);
Gfx::OSamplerState backgroundSampler = graphics->createSamplerState({});
Gfx::OSampler backgroundSampler = graphics->createSampler({});
info = {
.sourceData = {
@@ -181,7 +140,6 @@ void UIPass::createRenderPass()
renderPass = graphics->createRenderPass(std::move(layout), viewport);
Gfx::LegacyPipelineCreateInfo pipelineInfo;
pipelineInfo.vertexDeclaration = declaration;
pipelineInfo.vertexShader = vertexShader;
pipelineInfo.fragmentShader = fragmentShader;
pipelineInfo.renderPass = renderPass;
+1 -2
View File
@@ -1,7 +1,7 @@
#pragma once
#include "RenderPass.h"
#include "UI/RenderHierarchy.h"
#include "Graphics/Resources.h"
#include "Graphics/Shader.h"
namespace Seele
{
@@ -31,7 +31,6 @@ private:
Gfx::OUniformBuffer numTexturesBuffer;
Gfx::OVertexBuffer elementBuffer;
Gfx::OVertexDeclaration declaration;
Gfx::OVertexShader vertexShader;
Gfx::OFragmentShader fragmentShader;
Gfx::PGraphicsPipeline pipeline;
+8 -8
View File
@@ -38,10 +38,10 @@ Matrix4 Viewport::getProjectionMatrix() const
}
}
RenderTargetAttachment::RenderTargetAttachment(PTexture2D texture,
SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD,
SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE,
SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE,
SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE)
SeAttachmentLoadOp loadOp,
SeAttachmentStoreOp storeOp,
SeAttachmentLoadOp stencilLoadOp,
SeAttachmentStoreOp stencilStoreOp)
: clear()
, componentFlags(0)
, loadOp(loadOp)
@@ -57,10 +57,10 @@ RenderTargetAttachment::~RenderTargetAttachment()
}
SwapchainAttachment::SwapchainAttachment(PWindow owner,
SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD,
SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE,
SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE,
SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE)
SeAttachmentLoadOp loadOp,
SeAttachmentStoreOp storeOp,
SeAttachmentLoadOp stencilLoadOp,
SeAttachmentStoreOp stencilStoreOp)
: RenderTargetAttachment(nullptr, loadOp, storeOp, stencilLoadOp, stencilStoreOp), owner(owner)
{
clear.color.float32[0] = 0.0f;
+2 -2
View File
@@ -149,7 +149,7 @@ void StaticMeshVertexData::resizeBuffers()
.sourceData = {
.size = verticesAllocated * sizeof(Vector),
},
.stride = sizeof(Vector),
.numElements = verticesAllocated * 3,
.dynamic = true,
};
positions = graphics->createShaderBuffer(createInfo);
@@ -158,7 +158,7 @@ void StaticMeshVertexData::resizeBuffers()
biTangents = graphics->createShaderBuffer(createInfo);
colors = graphics->createShaderBuffer(createInfo);
createInfo.sourceData.size = verticesAllocated * sizeof(Vector2);
createInfo.stride = sizeof(Vector2);
createInfo.numElements = verticesAllocated * 2;
texCoords = graphics->createShaderBuffer(createInfo);
positionData.resize(verticesAllocated);
+11 -8
View File
@@ -5,6 +5,7 @@
#include "Graphics/Graphics.h"
#include "Graphics/Descriptor.h"
#include "Component/Mesh.h"
#include "Graphics/Shader.h"
using namespace Seele;
@@ -62,7 +63,8 @@ void VertexData::createDescriptors()
.size = sizeof(InstanceData) * instanceData.size(),
.data = (uint8*)instanceData.data(),
},
.stride = sizeof(InstanceData)
.numElements = instanceData.size(),
.dynamic = false,
});
matInst.descriptorSet = instanceDataLayout->allocateDescriptorSet();
matInst.descriptorSet->updateBuffer(0, matInst.instanceBuffer);
@@ -73,7 +75,8 @@ void VertexData::createDescriptors()
.size = sizeof(MeshData) * meshes.size(),
.data = (uint8*)meshes.data(),
},
.stride = sizeof(MeshData)
.numElements = meshes.size(),
.dynamic = false,
});
matInst.descriptorSet->updateBuffer(1, matInst.meshDataBuffer);
matInst.descriptorSet->updateBuffer(2, meshletBuffer);
@@ -123,25 +126,25 @@ void VertexData::loadMesh(MeshId id, Array<Meshlet> loadedMeshlets)
.size = sizeof(MeshletDescription) * meshlets.size(),
.data = (uint8*)meshlets.data()
},
.stride = sizeof(MeshletDescription),
.numElements = meshlets.size(),
.dynamic = true,
});
});
vertexIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData = {
.size = sizeof(uint32) * vertexIndices.size(),
.data = (uint8*)vertexIndices.data(),
},
.stride = sizeof(uint32),
.numElements = vertexIndices.size(),
.dynamic = true,
});
});
primitiveIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData = {
.size = sizeof(uint8) * primitiveIndices.size(),
.data = (uint8*)primitiveIndices.data(),
},
.stride = sizeof(uint8),
.numElements = primitiveIndices.size(),
.dynamic = true,
});
});
}
MeshId VertexData::allocateVertexData(uint64 numVertices)
+1 -1
View File
@@ -3,7 +3,7 @@
#include "Material/MaterialInstance.h"
#include "Component/Transform.h"
#include "Containers/List.h"
#include "Graphics/Resources.h"
#include "Graphics/Command.h"
#include "Graphics/Descriptor.h"
#include "Graphics/Buffer.h"
+16 -18
View File
@@ -1,7 +1,8 @@
#include "Allocator.h"
#include "Graphics.h"
#include "Initializer.h"
#include "Resources.h"
#include "Enums.h"
#include "Command.h"
using namespace Seele::Vulkan;
@@ -24,11 +25,6 @@ VkDeviceMemory SubAllocation::getHandle() const
return owner->getHandle();
}
bool SubAllocation::isReadable() const
{
return owner->isReadable();
}
void *SubAllocation::map()
{
return (uint8 *)owner->map() + alignedOffset;
@@ -44,14 +40,14 @@ void SubAllocation::invalidate()
owner->invalidate();
}
Allocation::Allocation(PGraphics graphics, PAllocator allocator, VkDeviceSize size, uint8 memoryTypeIndex,
Allocation::Allocation(PGraphics graphics, PAllocator pool, VkDeviceSize size, uint8 memoryTypeIndex,
VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo)
: device(graphics->getDevice())
, allocator(allocator)
, pool(pool)
, bytesAllocated(0)
, bytesUsed(0)
, canMap((properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT),
, isMapped(false),
, canMap((properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
, isMapped(false)
, properties(properties)
, memoryTypeIndex(memoryTypeIndex)
{
@@ -97,7 +93,7 @@ OSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice
alignedOffset /= alignment;
alignedOffset *= alignment;
VkDeviceSize allocatedSize = requestedSize + (alignedOffset - lower);
if (size <= allocatedSize)
if (size >= allocatedSize)
{
VkDeviceSize newSize = size - allocatedSize;
VkDeviceSize newLower = lower + allocatedSize;
@@ -140,7 +136,7 @@ void Allocation::markFree(PSubAllocation allocation)
bytesUsed -= allocation->allocatedSize;
if (bytesUsed == 0)
{
allocator->free(this);
pool->free(this);
}
}
@@ -209,7 +205,7 @@ OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2
{
OAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo);
heaps[heapIndex].inUse += newAllocation->bytesAllocated;
//std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl;
std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl;
heaps[heapIndex].allocations.add(std::move(newAllocation));
return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment);
}
@@ -229,7 +225,7 @@ OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2
// no suitable allocations found, allocate new block
OAllocation newAllocation = new Allocation(graphics, this, (requirements.size > DEFAULT_ALLOCATION) ? requirements.size : DEFAULT_ALLOCATION, memoryTypeIndex, properties, nullptr);
heaps[heapIndex].inUse += newAllocation->bytesAllocated;
//std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl;
std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl;
heaps[heapIndex].allocations.add(std::move(newAllocation));
return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment);
}
@@ -244,7 +240,7 @@ void Allocator::free(PAllocation allocation)
if (heaps[heapIndex].allocations[alloc] == allocation)
{
heaps[heapIndex].inUse -= allocation->bytesAllocated;
//std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl;
std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl;
heaps[heapIndex].allocations.removeAt(alloc, false);
return;
}
@@ -277,6 +273,8 @@ StagingBuffer::~StagingBuffer()
{
graphics->getDestructionManager()->queueBuffer(
graphics->getDedicatedTransferCommands()->getCommands(), buffer);
graphics->getDestructionManager()->queueAllocation(
graphics->getDedicatedTransferCommands()->getCommands(), std::move(allocation));
}
void* StagingBuffer::map()
@@ -314,8 +312,8 @@ void StagingBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::Se
assert(false);
}
StagingManager::StagingManager(PGraphics graphics, PAllocator allocator)
: graphics(graphics), allocator(allocator)
StagingManager::StagingManager(PGraphics graphics, PAllocator pool)
: graphics(graphics), pool(pool)
{
}
@@ -358,7 +356,7 @@ OStagingBuffer StagingManager::create(uint64 size)
OStagingBuffer stagingBuffer = new StagingBuffer(
graphics,
allocator->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT, buffer),
pool->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT, buffer),
buffer,
size
);
+17 -17
View File
@@ -30,8 +30,6 @@ public:
return alignedOffset;
}
bool isReadable() const;
void *map();
void flushMemory();
void invalidate();
@@ -49,7 +47,7 @@ DEFINE_REF(SubAllocation)
class Allocation
{
public:
Allocation(PGraphics graphics, PAllocator allocator, VkDeviceSize size, uint8 memoryTypeIndex,
Allocation(PGraphics graphics, PAllocator pool, VkDeviceSize size, uint8 memoryTypeIndex,
VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo = nullptr);
~Allocation();
OSubAllocation getSuballocation(VkDeviceSize size, VkDeviceSize alignment);
@@ -78,16 +76,16 @@ public:
private:
VkDevice device;
PAllocator allocator;
PAllocator pool;
VkDeviceSize bytesAllocated;
VkDeviceSize bytesUsed;
VkDeviceMemory allocatedMemory;
Array<PSubAllocation> activeAllocations;
Map<VkDeviceSize, VkDeviceSize> freeRanges;
void *mappedPointer;
uint8 isDedicated : 1;
uint8 canMap : 1;
uint8 isMapped : 1;
uint8 isDedicated : 1;
VkMemoryPropertyFlags properties;
uint8 memoryTypeIndex;
friend class Allocator;
@@ -104,21 +102,23 @@ public:
OSubAllocation allocate(const VkMemoryRequirements2 &requirements, VkMemoryPropertyFlags props,
VkBuffer buffer)
{
VkMemoryDedicatedAllocateInfo allocInfo;
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
allocInfo.pNext = nullptr;
allocInfo.buffer = buffer;
allocInfo.image = VK_NULL_HANDLE;
VkMemoryDedicatedAllocateInfo allocInfo = {
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
.pNext = nullptr,
.image = VK_NULL_HANDLE,
.buffer = buffer,
};
return allocate(requirements, props, &allocInfo);
}
OSubAllocation allocate(const VkMemoryRequirements2 &requirements, VkMemoryPropertyFlags props,
VkImage image)
{
VkMemoryDedicatedAllocateInfo allocInfo;
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
allocInfo.pNext = nullptr;
allocInfo.buffer = VK_NULL_HANDLE;
allocInfo.image = image;
VkMemoryDedicatedAllocateInfo allocInfo = {
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
.pNext = nullptr,
.image = image,
.buffer = VK_NULL_HANDLE,
};
return allocate(requirements, props, &allocInfo);
}
@@ -174,13 +174,13 @@ DEFINE_REF(StagingBuffer)
class StagingManager
{
public:
StagingManager(PGraphics graphics, PAllocator allocator);
StagingManager(PGraphics graphics, PAllocator pool);
~StagingManager();
OStagingBuffer create(uint64 size);
private:
PGraphics graphics;
PAllocator allocator;
PAllocator pool;
};
DEFINE_REF(StagingManager)
} // namespace Vulkan
+68 -61
View File
@@ -1,6 +1,5 @@
#include "Buffer.h"
#include "Initializer.h"
#include "CommandBuffer.h"
#include "Command.h"
using namespace Seele;
using namespace Seele::Vulkan;
@@ -79,15 +78,19 @@ VkDeviceSize Buffer::getOffset() const
void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
VkBufferMemoryBarrier barrier =
init::BufferMemoryBarrier();
PCommandBufferManager sourceManager = graphics->getQueueCommands(owner);
PCommandBufferManager dstManager = nullptr;
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
VkBufferMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner),
.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner),
.offset = 0,
.size = size,
};
PCommandPool sourcePool = graphics->getQueueCommands(owner);
PCommandPool dstPool = nullptr;
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
barrier.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner);
barrier.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner);
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
if (owner == Gfx::QueueType::TRANSFER || owner == Gfx::QueueType::DEDICATED_TRANSFER)
{
@@ -108,31 +111,29 @@ void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstManager = graphics->getTransferCommands();
dstPool = graphics->getTransferCommands();
}
else if (newOwner == Gfx::QueueType::DEDICATED_TRANSFER)
{
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstManager = graphics->getDedicatedTransferCommands();
dstPool = graphics->getDedicatedTransferCommands();
}
else if (newOwner == Gfx::QueueType::COMPUTE)
{
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
dstManager = graphics->getComputeCommands();
dstPool = graphics->getComputeCommands();
}
else if (newOwner == Gfx::QueueType::GRAPHICS)
{
barrier.dstAccessMask = getDestAccessMask();
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
dstManager = graphics->getGraphicsCommands();
dstPool = graphics->getGraphicsCommands();
}
VkCommandBuffer srcCommand = sourceManager->getCommands()->getHandle();
VkCommandBuffer dstCommand = dstManager->getCommands()->getHandle();
VkCommandBuffer srcCommand = sourcePool->getCommands()->getHandle();
VkCommandBuffer dstCommand = dstPool->getCommands()->getHandle();
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
barrier.offset = 0;
barrier.size = size;
for (uint32 i = 0; i < numBuffers; ++i)
{
dynamicBarriers[i] = barrier;
@@ -140,20 +141,23 @@ void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
}
vkCmdPipelineBarrier(srcCommand, srcStage, srcStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
vkCmdPipelineBarrier(dstCommand, dstStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
sourceManager->submitCommands();
sourcePool->submitCommands();
}
void Buffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
PCmdBuffer commandBuffer = graphics->getQueueCommands(owner)->getCommands();
VkBufferMemoryBarrier barrier = init::BufferMemoryBarrier();
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstAccessMask = dstAccess;
barrier.srcAccessMask = srcAccess;
barrier.offset = 0;
barrier.size = size;
PCommand commandBuffer = graphics->getQueueCommands(owner)->getCommands();
VkBufferMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = srcAccess,
.dstAccessMask = dstAccess,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.offset = 0,
.size = size,
};
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
for(uint32 i = 0; i < numBuffers; ++i)
{
@@ -194,35 +198,38 @@ void * Buffer::mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly)
if (writeOnly)
{
//requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
OStagingBuffer stagingBuffer = graphics->getStagingManager()->create(regionSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
OStagingBuffer stagingBuffer = graphics->getStagingManager()->create(regionSize);
data = stagingBuffer->map();
pending.stagingBuffer = std::move(stagingBuffer);
}
else
{
PCmdBuffer current = graphics->getQueueCommands(owner)->getCommands();
PCommand current = graphics->getQueueCommands(owner)->getCommands();
current->waitForCommand();
requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
VkCommandBuffer handle = graphics->getQueueCommands(owner)->getCommands()->getHandle();
VkBufferMemoryBarrier barrier =
init::BufferMemoryBarrier();
barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
barrier.buffer = buffers[currentBuffer].buffer;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.offset = 0;
barrier.size = size;
VkBufferMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[currentBuffer].buffer,
.offset = 0,
.size = size,
};
vkCmdPipelineBarrier(handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr);
OStagingBuffer stagingBuffer = graphics->getStagingManager()->create(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true);
OStagingBuffer stagingBuffer = graphics->getStagingManager()->create(size);
VkBufferCopy regions;
regions.size = size;
regions.srcOffset = 0;
regions.dstOffset = 0;
VkBufferCopy regions = {
.srcOffset = 0,
.dstOffset = 0,
.size = size,
};
vkCmdCopyBuffer(handle, buffers[currentBuffer].buffer, stagingBuffer->getHandle(), 1, &regions);
@@ -251,18 +258,18 @@ void Buffer::unmap()
if (pending.writeOnly)
{
PStagingBuffer stagingBuffer = pending.stagingBuffer;
PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
PCommand command = graphics->getQueueCommands(owner)->getCommands();
VkCommandBuffer cmdHandle = command->getHandle();
VkBufferCopy region;
std::memset(&region, 0, sizeof(VkBufferCopy));
region.size = pending.size;
region.dstOffset = pending.offset;
VkBufferCopy region = {
.srcOffset = 0,
.dstOffset = pending.offset,
.size = pending.size,
};
vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, &region);
graphics->getQueueCommands(owner)->submitCommands();
}
//requestOwnershipTransfer(pending.prevQueue);
graphics->getStagingManager()->release(std::move(pending.stagingBuffer));
pendingBuffers.erase(this);
}
}
@@ -274,7 +281,7 @@ UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &
{
if(createInfo.dynamic)
{
dedicatedStagingBuffer = graphics->getStagingManager()->create(createInfo.sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
dedicatedStagingBuffer = graphics->getStagingManager()->create(createInfo.sourceData.size);
}
if (createInfo.sourceData.data != nullptr)
{
@@ -286,7 +293,6 @@ UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &
UniformBuffer::~UniformBuffer()
{
graphics->getStagingManager()->release(std::move(dedicatedStagingBuffer));
}
bool UniformBuffer::updateContents(const DataSource &sourceData)
@@ -315,8 +321,8 @@ void UniformBuffer::unmap()
if(dedicatedStagingBuffer != nullptr)
{
dedicatedStagingBuffer->flush();
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
PCommand command = graphics->getQueueCommands(currentOwner)->getCommands();
VkCommandBuffer cmdHandle = command->getHandle();
VkBufferCopy region;
std::memset(&region, 0, sizeof(VkBufferCopy));
@@ -357,13 +363,13 @@ VkAccessFlags UniformBuffer::getDestAccessMask()
}
ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &sourceData)
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), sourceData.stride, sourceData.sourceData.size / sourceData.stride, sourceData.sourceData)
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), sourceData.numElements, sourceData.sourceData)
, Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, sourceData.dynamic)
, dedicatedStagingBuffer(nullptr)
{
if(sourceData.dynamic)
{
dedicatedStagingBuffer = graphics->getStagingManager()->create(sourceData.sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
dedicatedStagingBuffer = graphics->getStagingManager()->create(sourceData.sourceData.size);
}
if (sourceData.sourceData.data != nullptr)
{
@@ -375,7 +381,6 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &sou
ShaderBuffer::~ShaderBuffer()
{
graphics->getStagingManager()->release(std::move(dedicatedStagingBuffer));
}
bool ShaderBuffer::updateContents(const DataSource &sourceData)
@@ -402,12 +407,14 @@ void ShaderBuffer::unmap()
if(dedicatedStagingBuffer != nullptr)
{
dedicatedStagingBuffer->flush();
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
PCommand command = graphics->getQueueCommands(currentOwner)->getCommands();
VkCommandBuffer cmdHandle = command->getHandle();
VkBufferCopy region;
std::memset(&region, 0, sizeof(VkBufferCopy));
region.size = Vulkan::Buffer::size;
VkBufferCopy region = {
.srcOffset = 0,
.dstOffset = 0,
.size = Vulkan::Buffer::size,
};
vkCmdCopyBuffer(cmdHandle, dedicatedStagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, &region);
graphics->getQueueCommands(currentOwner)->submitCommands();
}
+4 -4
View File
@@ -6,6 +6,8 @@ target_sources(Engine
Buffer.cpp
Command.h
Command.cpp
Debug.h
Debug.cpp
Descriptor.h
Descriptor.cpp
Enums.h
@@ -14,8 +16,6 @@ target_sources(Engine
Framebuffer.cpp
Graphics.h
Graphics.cpp
Initializer.h
Initializer.cpp
Pipeline.h
Pipeline.cpp
PipelineCache.h
@@ -39,11 +39,11 @@ target_sources(Engine
Allocator.h
Buffer.h
Command.h
DescriptorSets.h
Debug.h
Descriptor.h
Enums.h
Framebuffer.h
Graphics.h
Initializer.h
Pipeline.h
PipelineCache.h
Queue.h
+77 -62
View File
@@ -1,12 +1,11 @@
#include "CommandBuffer.h"
#include "Initializer.h"
#include "Command.h"
#include "Graphics.h"
#include "Pipeline.h"
#include "Enums.h"
#include "Framebuffer.h"
#include "RenderPass.h"
#include "Pipeline.h"
#include "DescriptorSets.h"
#include "Descriptor.h"
#include "RenderTarget.h"
#include <vulkan/vulkan_core.h>
@@ -14,9 +13,9 @@ using namespace Seele;
using namespace Seele::Vulkan;
Command::Command(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferManager manager)
Command::Command(PGraphics graphics, VkCommandPool cmdPool, PCommandPool pool)
: graphics(graphics)
, manager(manager)
, pool(pool)
, owner(cmdPool)
{
VkCommandBufferAllocateInfo allocInfo = {
@@ -159,7 +158,7 @@ void Command::checkFence()
void Command::waitForCommand(uint32 timeout)
{
manager->submitCommands();
pool->submitCommands();
if (state == State::Begin)
{
// is already done
@@ -174,9 +173,9 @@ PFence Command::getFence()
return fence;
}
PCommandBufferManager Command::getManager()
PCommandPool Command::getPool()
{
return manager;
return pool;
}
RenderCommand::RenderCommand(PGraphics graphics, VkCommandPool cmdPool)
@@ -203,15 +202,21 @@ void RenderCommand::begin(PRenderPass renderPass, PFramebuffer framebuffer)
{
threadId = std::this_thread::get_id();
ready = false;
VkCommandBufferBeginInfo beginInfo =
init::CommandBufferBeginInfo();
VkCommandBufferInheritanceInfo inheritanceInfo =
init::CommandBufferInheritanceInfo();
inheritanceInfo.framebuffer = framebuffer->getHandle();
inheritanceInfo.renderPass = renderPass->getHandle();
inheritanceInfo.subpass = 0;
beginInfo.pInheritanceInfo = &inheritanceInfo;
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
VkCommandBufferInheritanceInfo inheritanceInfo = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
.renderPass = renderPass->getHandle(),
.subpass = 0,
.framebuffer = framebuffer->getHandle(),
.occlusionQueryEnable = 0,
.queryFlags = 0,
.pipelineStatistics = 0,
};
VkCommandBufferBeginInfo beginInfo = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.pNext = nullptr,
.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
.pInheritanceInfo = &inheritanceInfo,
};
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
}
@@ -236,7 +241,16 @@ void RenderCommand::setViewport(Gfx::PViewport viewport)
{
assert(threadId == std::this_thread::get_id());
VkViewport vp = viewport.cast<Viewport>()->getHandle();
VkRect2D scissors = init::Rect2D(viewport->getWidth(), viewport->getHeight(), viewport->getOffsetX(), viewport->getOffsetY());
VkRect2D scissors = {
.offset = {
.x = (int32)viewport->getOffsetX(),
.y = (int32)viewport->getOffsetY(),
},
.extent = {
.width = viewport->getWidth(),
.height = viewport->getHeight(),
},
};
vkCmdSetViewport(handle, 0, 1, &vp);
vkCmdSetScissor(handle, 0, 1, &scissors);
}
@@ -321,10 +335,13 @@ ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool)
: graphics(graphics)
, owner(cmdPool)
{
VkCommandBufferAllocateInfo allocInfo =
init::CommandBufferAllocateInfo(cmdPool,
VK_COMMAND_BUFFER_LEVEL_SECONDARY,
1);
VkCommandBufferAllocateInfo allocInfo = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.pNext = nullptr,
.commandPool = owner,
.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY,
.commandBufferCount = 1,
};
VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle));
}
@@ -334,18 +351,25 @@ ComputeCommand::~ComputeCommand()
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
}
void ComputeCommand::begin(PCmdBuffer)
void ComputeCommand::begin()
{
threadId = std::this_thread::get_id();
ready = false;
VkCommandBufferBeginInfo beginInfo =
init::CommandBufferBeginInfo();
VkCommandBufferInheritanceInfo inheritanceInfo =
init::CommandBufferInheritanceInfo();
inheritanceInfo.framebuffer = VK_NULL_HANDLE;
inheritanceInfo.renderPass = VK_NULL_HANDLE;
inheritanceInfo.subpass = 0;
beginInfo.pInheritanceInfo = &inheritanceInfo;
VkCommandBufferInheritanceInfo inheritanceInfo = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
.renderPass = VK_NULL_HANDLE,
.subpass = 0,
.framebuffer = VK_NULL_HANDLE,
.occlusionQueryEnable = 0,
.queryFlags = 0,
.pipelineStatistics = 0,
};
VkCommandBufferBeginInfo beginInfo = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.pNext = nullptr,
.flags = 0,
.pInheritanceInfo = &inheritanceInfo,
};
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
}
@@ -419,16 +443,16 @@ void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ)
CommandPool::CommandPool(PGraphics graphics, PQueue queue)
: graphics(graphics), queue(queue), queueFamilyIndex(queue->getFamilyIndex())
{
VkCommandPoolCreateInfo info =
init::CommandPoolCreateInfo();
info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
info.queueFamilyIndex = queue->getFamilyIndex();
VkCommandPoolCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.pNext = nullptr,
.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
.queueFamilyIndex = queue->getFamilyIndex(),
};
VK_CHECK(vkCreateCommandPool(graphics->getDevice(), &info, nullptr, &commandPool));
allocatedBuffers.add(new Command(graphics, commandPool, this));
command = allocatedBuffers.back();
command->begin();
}
@@ -440,74 +464,65 @@ CommandPool::~CommandPool()
queue = nullptr;
}
PCmdBuffer CommandPool::getCommands()
PCommand CommandPool::getCommands()
{
return command;
}
PRenderCommand CommandPool::createRenderCommand(PRenderPass renderPass, PFramebuffer framebuffer, const std::string& name)
PRenderCommand CommandPool::createRenderCommand(const std::string& name)
{
std::scoped_lock lck(allocatedRenderLock);
for (uint32 i = 0; i < allocatedRenderCommands.size(); ++i)
{
PRenderCommand cmdBuffer = allocatedRenderCommands[i];
if (cmdBuffer->isReady())
{
cmdBuffer->name = name;
cmdBuffer->begin(renderPass, framebuffer);
cmdBuffer->begin(command->boundRenderPass, command->boundFramebuffer);
return cmdBuffer;
}
}
allocatedRenderCommands.add(new RenderCommand(graphics, commandPool));
PRenderCommand result = allocatedRenderCommands.back();
result->name = name;
result->begin(renderPass, framebuffer);
result->begin(command->boundRenderPass, command->boundFramebuffer);
return result;
}
PComputeCommand CommandPool::createComputeCommand(const std::string& name)
{
std::scoped_lock lck(allocatedComputeLock);
for (uint32 i = 0; i < allocatedComputeCommands.size(); ++i)
{
PComputeCommand cmdBuffer = allocatedComputeCommands[i];
if (cmdBuffer->isReady())
{
cmdBuffer->name = name;
cmdBuffer->begin(command);
cmdBuffer->begin();
return cmdBuffer;
}
}
allocatedComputeCommands.add(new ComputeCommand(graphics, commandPool));
PComputeCommand result = allocatedComputeCommands.back();
result->name = name;
result->begin(command);
result->begin();
return result;
}
void CommandPool::submitCommands(PSemaphore signalSemaphore)
{
if (command->state == Command::State::Begin || command->state == Command::State::RenderPass)
assert(command->state == Command::State::Begin); // Not in a renderpass
command->end();
if (signalSemaphore != nullptr)
{
if (command->state == Command::State::RenderPass)
{
std::cout << "End of renderpass forced" << std::endl;
command->endRenderPass();
}
command->end();
if (signalSemaphore != nullptr)
{
queue->submitCommandBuffer(command, signalSemaphore->getHandle());
}
else
{
queue->submitCommandBuffer(command);
}
queue->submitCommandBuffer(command, signalSemaphore->getHandle());
}
std::scoped_lock map(allocatedBufferLock);
else
{
queue->submitCommandBuffer(command);
}
for (uint32 i = 0; i < allocatedBuffers.size(); ++i)
{
PCmdBuffer cmdBuffer = allocatedBuffers[i];
PCommand cmdBuffer = allocatedBuffers[i];
cmdBuffer->checkFence();
if (cmdBuffer->state == Command::State::Init)
{
+9 -7
View File
@@ -1,6 +1,6 @@
#pragma once
#include "Queue.h"
#include "DescriptorSets.h"
#include "Graphics/Command.h"
#include "Buffer.h"
namespace Seele
@@ -17,7 +17,7 @@ DECLARE_REF(CommandPool)
class Command
{
public:
Command(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferManager manager);
Command(PGraphics graphics, VkCommandPool cmdPool, PCommandPool pool);
virtual ~Command();
constexpr VkCommandBuffer getHandle()
{
@@ -34,7 +34,7 @@ public:
void checkFence();
void waitForCommand(uint32 timeToWait = 1000000u);
PFence getFence();
PCommandBufferManager getManager();
PCommandPool getPool();
enum State
{
Init,
@@ -46,13 +46,15 @@ public:
private:
PGraphics graphics;
PCommandBufferManager manager;
PCommandPool pool;
OFence fence;
State state;
VkViewport currentViewport;
VkRect2D currentScissor;
VkCommandBuffer handle;
VkCommandPool owner;
PRenderPass boundRenderPass;
PFramebuffer boundFramebuffer;
Array<PSemaphore> waitSemaphores;
Array<VkPipelineStageFlags> waitFlags;
Array<PRenderCommand> executingRenders;
@@ -112,7 +114,7 @@ public:
{
return handle;
}
void begin(PCmdBuffer parent);
void begin();
void end();
void reset();
virtual bool isReady() override;
@@ -144,7 +146,7 @@ public:
return queue;
}
PCommand getCommands();
PRenderCommand createRenderCommand(PRenderPass renderPass, PFramebuffer framebuffer, const std::string& name);
PRenderCommand createRenderCommand(const std::string& name);
PComputeCommand createComputeCommand(const std::string& name);
constexpr VkCommandPool getHandle() const
{
@@ -158,7 +160,7 @@ private:
PQueue queue;
uint32 queueFamilyIndex;
PCommand command;
Array<OCmdBuffer> allocatedBuffers;
Array<OCommand> allocatedBuffers;
Array<ORenderCommand> allocatedRenderCommands;
Array<OComputeCommand> allocatedComputeCommands;
};
+32
View File
@@ -0,0 +1,32 @@
#include "Debug.h"
#include <iostream>
using namespace Seele::Vulkan;
VkBool32 Seele::Vulkan::debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT, uint64_t, size_t, int32_t, const char *layerPrefix, const char *msg, void *)
{
std::cerr << layerPrefix << ": " << msg << std::endl;
return VK_FALSE;
}
VkResult Seele::Vulkan::CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback)
{
auto func = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");
if (func != nullptr)
{
return func(instance, pCreateInfo, pAllocator, pCallback);
}
else
{
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
}
void Seele::Vulkan::DestroyDebugReportCallbackEXT(VkInstance instance, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT pCallback)
{
auto func = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT");
if (func != nullptr)
{
func(instance, pCallback, pAllocator);
}
}
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include "Containers/Array.h"
#include <vulkan/vulkan.h>
namespace Seele
{
namespace Vulkan
{
VkBool32 debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char *layerPrefix, const char *msg, void *userData);
VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback);
void DestroyDebugReportCallbackEXT(VkInstance instance, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT pCallback);
} // namespace Vulkan
} // namespace Seele
+136 -96
View File
@@ -1,8 +1,7 @@
#include "DescriptorSets.h"
#include "Descriptor.h"
#include "Graphics.h"
#include "Initializer.h"
#include "CommandBuffer.h"
#include "Texture.h"
#include "Buffer.h"
using namespace Seele;
using namespace Seele::Vulkan;
@@ -31,27 +30,32 @@ void DescriptorLayout::create()
Array<VkDescriptorBindingFlags> bindingFlags(descriptorBindings.size());
for (size_t i = 0; i < descriptorBindings.size(); ++i)
{
VkDescriptorSetLayoutBinding &binding = bindings[i];
const Gfx::DescriptorBinding &gfxBinding = descriptorBindings[i];
binding.binding = gfxBinding.binding;
binding.descriptorCount = gfxBinding.descriptorCount;
binding.descriptorType = cast(gfxBinding.descriptorType);
binding.stageFlags = gfxBinding.shaderStages;
binding.pImmutableSamplers = nullptr;
bindings[i] = {
.binding = gfxBinding.binding,
.descriptorType = cast(gfxBinding.descriptorType),
.descriptorCount = gfxBinding.descriptorCount,
.stageFlags = gfxBinding.shaderStages,
.pImmutableSamplers = nullptr,
};
bindingFlags[i] = gfxBinding.bindingFlags;
}
VkDescriptorSetLayoutCreateInfo createInfo =
init::DescriptorSetLayoutCreateInfo(bindings.data(), (uint32)bindings.size());
VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
.pNext = nullptr,
.bindingCount = static_cast<uint32>(bindingFlags.size()),
.pBindingFlags = bindingFlags.data(),
};
createInfo.pNext = &bindingFlagsInfo;
VkDescriptorSetLayoutCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.pNext = &bindingFlagsInfo,
.flags = 0,
.bindingCount = (uint32)bindings.size(),
.pBindings = bindings.data(),
};
VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
allocator = new DescriptorAllocator(graphics, *this);
pool = new DescriptorPool(graphics, *this);
hash = CRC::Calculate(bindings.data(), sizeof(VkDescriptorSetLayoutBinding) * bindings.size(), CRC::CRC_32());
}
@@ -60,12 +64,10 @@ PipelineLayout::~PipelineLayout()
{
if (layoutHandle != VK_NULL_HANDLE)
{
//vkDestroyPipelineLayout(graphics->getDevice(), layoutHandle, nullptr);
vkDestroyPipelineLayout(graphics->getDevice(), layoutHandle, nullptr);
}
}
static Map<uint32, VkPipelineLayout> layoutCache;
void PipelineLayout::create()
{
vulkanDescriptorLayouts.resize(descriptorSetLayouts.size());
@@ -82,8 +84,6 @@ void PipelineLayout::create()
vulkanDescriptorLayouts[i] = layout->getHandle();
}
VkPipelineLayoutCreateInfo createInfo =
init::PipelineLayoutCreateInfo(vulkanDescriptorLayouts.data(), (uint32)vulkanDescriptorLayouts.size());
Array<VkPushConstantRange> vkPushConstants(pushConstants.size());
for (size_t i = 0; i < pushConstants.size(); i++)
{
@@ -91,20 +91,21 @@ void PipelineLayout::create()
vkPushConstants[i].size = pushConstants[i].size;
vkPushConstants[i].stageFlags = (VkShaderStageFlagBits)pushConstants[i].stageFlags;
}
createInfo.pushConstantRangeCount = (uint32)vkPushConstants.size();
createInfo.pPushConstantRanges = vkPushConstants.data();
VkPipelineLayoutCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.setLayoutCount = (uint32)vulkanDescriptorLayouts.size(),
.pSetLayouts = vulkanDescriptorLayouts.data(),
.pushConstantRangeCount = (uint32)vkPushConstants.size(),
.pPushConstantRanges = vkPushConstants.data(),
};
layoutHash = CRC::Calculate(createInfo.pPushConstantRanges, sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount, CRC::CRC_32());
layoutHash = CRC::Calculate(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount, CRC::CRC_32(), layoutHash);
if(layoutCache[layoutHash] != VK_NULL_HANDLE)
{
layoutHandle = layoutCache[layoutHash];
return;
}
VK_CHECK(vkCreatePipelineLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
layoutCache[layoutHash] = layoutHandle;
}
void PipelineLayout::reset()
@@ -127,10 +128,22 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBu
//std::cout << "uniform data equal, skip" << std::endl;
return;
}
bufferInfos.add(init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize()));
bufferInfos.add(VkDescriptorBufferInfo{
.buffer = vulkanBuffer->getHandle(),
.offset = 0,
.range = vulkanBuffer->getSize(),
});
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, binding, &bufferInfos.back());
writeDescriptors.add(writeDescriptor);
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.pBufferInfo = &bufferInfos.back(),
});
cachedData[binding] = vulkanBuffer.getHandle();
}
@@ -143,55 +156,69 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuff
{
return;
}
bufferInfos.add(init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize()));
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, binding, &bufferInfos.back());
writeDescriptors.add(writeDescriptor);
bufferInfos.add(VkDescriptorBufferInfo{
.buffer = vulkanBuffer->getHandle(),
.offset = 0,
.range = vulkanBuffer->getSize(),
});
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.pBufferInfo = &bufferInfos.back(),
});
cachedData[binding] = vulkanBuffer.getHandle();
}
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSamplerState samplerState)
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState)
{
PSamplerState vulkanSampler = samplerState.cast<Sampler>();
PSampler vulkanSampler = samplerState.cast<Sampler>();
Sampler* cachedSampler = reinterpret_cast<Sampler*>(cachedData[binding]);
if(vulkanSampler.getHandle() == cachedSampler)
{
return;
}
VkDescriptorImageInfo imageInfo =
init::DescriptorImageInfo(
vulkanSampler->sampler,
VK_NULL_HANDLE,
VK_IMAGE_LAYOUT_UNDEFINED);
imageInfos.add(imageInfo);
imageInfos.add(VkDescriptorImageInfo{
.sampler = vulkanSampler->sampler,
.imageView = VK_NULL_HANDLE,
.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
});
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_SAMPLER, binding, &imageInfos.back());
writeDescriptors.add(writeDescriptor);
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
.pImageInfo = &imageInfos.back(),
});
cachedData[binding] = vulkanSampler.getHandle();
}
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState samplerState)
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler samplerState)
{
TextureHandle* vulkanTexture = TextureBase::cast(texture);
TextureHandle* cachedTexture = reinterpret_cast<TextureHandle*>(cachedData[binding]);
TextureBase* vulkanTexture = texture.cast<TextureBase>().getHandle();
TextureBase* cachedTexture = reinterpret_cast<TextureBase*>(cachedData[binding]);
if(vulkanTexture == cachedTexture)
{
return;
}
//It is assumed that the image is in the correct layout
VkDescriptorImageInfo imageInfo =
init::DescriptorImageInfo(
VK_NULL_HANDLE,
vulkanTexture->getView(),
cast(vulkanTexture->getLayout()));
if (samplerState != nullptr)
{
PSamplerState vulkanSampler = samplerState.cast<Sampler>();
imageInfo.sampler = vulkanSampler->sampler;
}
imageInfos.add(imageInfo);
imageInfos.add(VkDescriptorImageInfo{
.sampler = samplerState != nullptr ? samplerState.cast<Sampler>()->sampler : VK_NULL_HANDLE,
.imageView = vulkanTexture->getView(),
.imageLayout = cast(vulkanTexture->getLayout()),
});
VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
if(samplerState != nullptr)
{
@@ -201,14 +228,16 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
{
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
}
VkWriteDescriptorSet writeDescriptor =
init::WriteDescriptorSet(
setHandle,
descriptorType,
binding,
&imageInfos.back());
writeDescriptors.add(writeDescriptor);
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = descriptorType,
.pImageInfo = &imageInfos.back(),
});
cachedData[binding] = vulkanTexture;
}
@@ -216,28 +245,30 @@ void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture> te
{
// maybe make this a parameter?
uint32 arrayElement = 0;
for(const auto& gfxTexture : textures)
for(auto& gfxTexture : textures)
{
TextureHandle* vulkanTexture = TextureBase::cast(gfxTexture);
imageInfos.add(
init::DescriptorImageInfo(
VK_NULL_HANDLE,
vulkanTexture->getView(),
cast(vulkanTexture->getLayout())));
TextureBase* vulkanTexture = gfxTexture.cast<TextureBase>().getHandle();
imageInfos.add(VkDescriptorImageInfo{
.sampler = VK_NULL_HANDLE,
.imageView = vulkanTexture->getView(),
.imageLayout = cast(vulkanTexture->getLayout()),
});
VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT)
{
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
}
VkWriteDescriptorSet& write = writeDescriptors.add(
init::WriteDescriptorSet(
setHandle,
descriptorType,
binding,
&imageInfos.back()
));
write.dstArrayElement = arrayElement++;
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = arrayElement++,
.descriptorCount = 1,
.descriptorType = descriptorType,
.pImageInfo = &imageInfos.back(),
});
}
}
@@ -268,7 +299,7 @@ void DescriptorSet::writeChanges()
}
}
DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout &layout)
DescriptorPool::DescriptorPool(PGraphics graphics, DescriptorLayout &layout)
: graphics(graphics)
, layout(layout)
{
@@ -296,15 +327,18 @@ DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout &l
poolSizes.add(size);
}
}
VkDescriptorPoolCreateInfo createInfo
= init::DescriptorPoolCreateInfo(
(uint32)poolSizes.size(),
poolSizes.data(),
maxSets * Gfx::numFramesBuffered);
VkDescriptorPoolCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.maxSets = maxSets * Gfx::numFramesBuffered,
.poolSizeCount = (uint32)poolSizes.size(),
.pPoolSizes = poolSizes.data(),
};
VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle));
}
DescriptorAllocator::~DescriptorAllocator()
DescriptorPool::~DescriptorPool()
{
vkDestroyDescriptorPool(graphics->getDevice(), poolHandle, nullptr);
graphics = nullptr;
@@ -314,15 +348,21 @@ DescriptorAllocator::~DescriptorAllocator()
}
}
Gfx::PDescriptorSet DescriptorAllocator::allocateDescriptorSet()
Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet()
{
VkDescriptorSetLayout layoutHandle = layout.getHandle();
VkDescriptorSetAllocateInfo allocInfo =
init::DescriptorSetAllocateInfo(poolHandle, &layoutHandle, 1);
VkDescriptorSetVariableDescriptorCountAllocateInfo setCounts = {};
setCounts.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO;
setCounts.pNext = nullptr;
setCounts.descriptorSetCount = 1;
VkDescriptorSetVariableDescriptorCountAllocateInfo setCounts = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
.pNext = nullptr,
.descriptorSetCount = 1,
};
VkDescriptorSetAllocateInfo allocInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.pNext = nullptr,
.descriptorPool = poolHandle,
.descriptorSetCount = 1,
.pSetLayouts = &layoutHandle,
};
uint32 counts = 0;
for(const auto& binding : layout.bindings)
{
@@ -364,13 +404,13 @@ Gfx::PDescriptorSet DescriptorAllocator::allocateDescriptorSet()
}
if(nextAlloc == nullptr)
{
nextAlloc = new DescriptorAllocator(graphics, layout);
nextAlloc = new DescriptorPool(graphics, layout);
}
return nextAlloc->allocateDescriptorSet();
//throw std::logic_error("Out of descriptor sets");
}
void DescriptorAllocator::reset()
void DescriptorPool::reset()
{
for(uint32 i = 0; i < cachedHandles.size(); ++i)
{
+14 -20
View File
@@ -24,7 +24,7 @@ private:
PGraphics graphics;
Array<VkDescriptorSetLayoutBinding> bindings;
VkDescriptorSetLayout layoutHandle;
friend class DescriptorAllocator;
friend class DescriptorPool;
};
DEFINE_REF(DescriptorLayout)
class PipelineLayout : public Gfx::PipelineLayout
@@ -33,25 +33,19 @@ public:
PipelineLayout(PGraphics graphics, Gfx::PPipelineLayout baseLayout)
: Gfx::PipelineLayout(baseLayout)
, graphics(graphics)
, layoutHash(0)
, layoutHandle(VK_NULL_HANDLE)
{}
virtual ~PipelineLayout();
virtual void create();
virtual void reset();
inline VkPipelineLayout getHandle() const
constexpr VkPipelineLayout getHandle() const
{
return layoutHandle;
}
virtual uint32 getHash() const
{
return layoutHash;
}
private:
Array<VkDescriptorSetLayout> vulkanDescriptorLayouts;
PGraphics graphics;
uint32 layoutHash;
VkPipelineLayout layoutHandle;
};
DEFINE_REF(PipelineLayout)
@@ -59,7 +53,7 @@ DEFINE_REF(PipelineLayout)
class DescriptorSet : public Gfx::DescriptorSet
{
public:
DescriptorSet(PGraphics graphics, PDescriptorAllocator owner)
DescriptorSet(PGraphics graphics, PDescriptorPool owner)
: setHandle(VK_NULL_HANDLE)
, graphics(graphics)
, owner(owner)
@@ -71,8 +65,8 @@ public:
virtual void writeChanges();
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer);
virtual void updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer);
virtual void updateSampler(uint32_t binding, Gfx::PSamplerState samplerState);
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState sampler = nullptr);
virtual void updateSampler(uint32_t binding, Gfx::PSampler samplerState);
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler sampler = nullptr);
virtual void updateTextureArray(uint32_t binding, Array<Gfx::PTexture> texture);
virtual bool operator<(Gfx::PDescriptorSet other);
@@ -116,29 +110,29 @@ private:
Array<void*> cachedData;
VkDescriptorSet setHandle;
PGraphics graphics;
PDescriptorAllocator owner;
PDescriptorPool owner;
bool currentlyBound;
bool currentlyInUse;
friend class DescriptorAllocator;
friend class DescriptorPool;
friend class Command;
friend class RenderCommand;
friend class ComputeCommand;
};
DEFINE_REF(DescriptorSet)
class DescriptorAllocator : public Gfx::DescriptorAllocator
class DescriptorPool : public Gfx::DescriptorPool
{
public:
DescriptorAllocator(PGraphics graphics, DescriptorLayout &layout);
virtual ~DescriptorAllocator();
DescriptorPool(PGraphics graphics, DescriptorLayout &layout);
virtual ~DescriptorPool();
virtual Gfx::PDescriptorSet allocateDescriptorSet() override;
virtual void reset();
inline VkDescriptorPool getHandle() const
constexpr VkDescriptorPool getHandle() const
{
return poolHandle;
}
inline DescriptorLayout& getLayout() const
constexpr DescriptorLayout& getLayout() const
{
return layout;
}
@@ -149,8 +143,8 @@ private:
const static int maxSets = 64;
StaticArray<ODescriptorSet, maxSets> cachedHandles;
VkDescriptorPool poolHandle;
DescriptorAllocator* nextAlloc = nullptr;
DescriptorPool* nextAlloc = nullptr;
};
DEFINE_REF(DescriptorAllocator)
DEFINE_REF(DescriptorPool)
} // namespace Vulkan
} // namespace Seele
+19 -18
View File
@@ -1,6 +1,5 @@
#include "Framebuffer.h"
#include "Enums.h"
#include "Initializer.h"
#include "RenderPass.h"
#include "Graphics.h"
#include "Texture.h"
@@ -16,41 +15,43 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::PRende
FramebufferDescription description;
std::memset(&description, 0, sizeof(FramebufferDescription));
Array<VkImageView> attachments;
uint32 sizeX = 0;
uint32 sizeY = 0;
uint32 width = 0;
uint32 height = 0;
for (auto inputAttachment : layout->inputAttachments)
{
PTexture2D vkInputAttachment = inputAttachment->getTexture().cast<Texture2D>();
attachments.add(vkInputAttachment->getView());
description.inputAttachments[description.numInputAttachments++] = vkInputAttachment->getView();
sizeX = std::max(sizeX, vkInputAttachment->getWidth());
sizeY = std::max(sizeY, vkInputAttachment->getHeight());
width = std::max(width, vkInputAttachment->getWidth());
height = std::max(height, vkInputAttachment->getHeight());
}
for (auto colorAttachment : layout->colorAttachments)
{
PTexture2D vkColorAttachment = colorAttachment->getTexture().cast<Texture2D>();
attachments.add(vkColorAttachment->getView());
description.colorAttachments[description.numColorAttachments++] = vkColorAttachment->getView();
sizeX = std::max(sizeX, vkColorAttachment->getWidth());
sizeY = std::max(sizeY, vkColorAttachment->getHeight());
width = std::max(width, vkColorAttachment->getWidth());
height = std::max(height, vkColorAttachment->getHeight());
}
if (layout->depthAttachment != nullptr)
{
PTexture2D vkDepthAttachment = layout->depthAttachment->getTexture().cast<Texture2D>();
attachments.add(vkDepthAttachment->getView());
description.depthAttachment = vkDepthAttachment->getView();
sizeX = std::max(sizeX, vkDepthAttachment->getWidth());
sizeY = std::max(sizeY, vkDepthAttachment->getHeight());
width = std::max(width, vkDepthAttachment->getWidth());
height = std::max(height, vkDepthAttachment->getHeight());
}
VkFramebufferCreateInfo createInfo =
init::FramebufferCreateInfo(
renderPass->getHandle(),
(uint32)attachments.size(),
attachments.data(),
sizeX,
sizeY,
1);
VkFramebufferCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.renderPass = renderPass->getHandle(),
.attachmentCount = (uint32)attachments.size(),
.pAttachments = attachments.data(),
.width = width,
.height = height,
.layers = 1,
};
VK_CHECK(vkCreateFramebuffer(graphics->getDevice(), &createInfo, nullptr, &handle));
hash = CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32());
+4 -4
View File
@@ -10,8 +10,8 @@ namespace Vulkan
DECLARE_REF(RenderPass)
struct FramebufferDescription
{
VkImageView inputAttachments[16];
VkImageView colorAttachments[16];
StaticArray<VkImageView, 16> inputAttachments;
StaticArray<VkImageView, 16> colorAttachments;
VkImageView depthAttachment;
uint32 numInputAttachments;
uint32 numColorAttachments;
@@ -21,11 +21,11 @@ class Framebuffer
public:
Framebuffer(PGraphics graphics, PRenderPass renderpass, Gfx::PRenderTargetLayout renderTargetLayout);
virtual ~Framebuffer();
inline VkFramebuffer getHandle() const
constexpr VkFramebuffer getHandle() const
{
return handle;
}
inline uint32 getHash() const
constexpr uint32 getHash() const
{
return hash;
}
+62 -78
View File
@@ -1,11 +1,11 @@
#include "Containers/Array.h"
#include "Graphics.h"
#include "Debug.h"
#include "Allocator.h"
#include "Buffer.h"
#include "Graphics/Enums.h"
#include "PipelineCache.h"
#include "Command.h"
#include "Initializer.h"
#include "Descriptor.h"
#include "RenderTarget.h"
#include "RenderPass.h"
#include "Framebuffer.h"
@@ -17,10 +17,10 @@
using namespace Seele;
using namespace Seele::Vulkan;
thread_local OCommandBufferManager Seele::Vulkan::Graphics::graphicsCommands = nullptr;
thread_local OCommandBufferManager Seele::Vulkan::Graphics::computeCommands = nullptr;
thread_local OCommandBufferManager Seele::Vulkan::Graphics::transferCommands = nullptr;
thread_local OCommandBufferManager Seele::Vulkan::Graphics::dedicatedTransferCommands = nullptr;
thread_local OCommandPool Seele::Vulkan::Graphics::graphicsCommands = nullptr;
thread_local OCommandPool Seele::Vulkan::Graphics::computeCommands = nullptr;
thread_local OCommandPool Seele::Vulkan::Graphics::transferCommands = nullptr;
thread_local OCommandPool Seele::Vulkan::Graphics::dedicatedTransferCommands = nullptr;
Graphics::Graphics()
: instance(VK_NULL_HANDLE)
@@ -32,7 +32,6 @@ Graphics::Graphics()
Graphics::~Graphics()
{
viewports.clear();
vkDestroyDevice(handle, nullptr);
DestroyDebugReportCallbackEXT(instance, nullptr, callback);
vkDestroyInstance(instance, nullptr);
@@ -54,21 +53,16 @@ void Graphics::init(GraphicsInitializer initInfo)
Gfx::OWindow Graphics::createWindow(const WindowCreateInfo &createInfo)
{
OWindow result = new Window(this, createInfo);
return result;
return new Window(this, createInfo);
}
Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreateInfo &viewportInfo)
{
OViewport result = new Viewport(this, owner, viewportInfo);
std::scoped_lock lock(viewportLock);
viewports.add(result);
return result;
return new Viewport(this, owner, viewportInfo);
}
Gfx::ORenderPass Graphics::createRenderPass(Gfx::ORenderTargetLayout layout, Gfx::PViewport renderArea)
{
ORenderPass result = new RenderPass(this, std::move(layout), renderArea);
return result;
return new RenderPass(this, std::move(layout), renderArea);
}
void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
{
@@ -76,7 +70,6 @@ void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
uint32 framebufferHash = rp->getFramebufferHash();
PFramebuffer framebuffer;
{
std::scoped_lock lock(allocatedFrameBufferLock);
auto found = allocatedFramebuffers.find(framebufferHash);
if (found == allocatedFramebuffers.end())
{
@@ -89,18 +82,12 @@ void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
}
}
getGraphicsCommands()->getCommands()->beginRenderPass(rp, framebuffer);
std::scoped_lock lock(renderPassLock);
activeRenderPass = rp;
activeFramebuffer = framebuffer;
}
void Graphics::endRenderPass()
{
getGraphicsCommands()->getCommands()->endRenderPass();
getGraphicsCommands()->submitCommands();
std::scoped_lock lock(renderPassLock);
activeRenderPass = nullptr;
activeFramebuffer = nullptr;
}
void Graphics::executeCommands(const Array<Gfx::PRenderCommand>& commands)
@@ -148,7 +135,7 @@ Gfx::OIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkD
}
Gfx::PRenderCommand Graphics::createRenderCommand(const std::string& name)
{
return getGraphicsCommands()->createRenderCommand(activeRenderPass, activeFramebuffer, name);
return getGraphicsCommands()->createRenderCommand(name);
}
Gfx::PComputeCommand Graphics::createComputeCommand(const std::string& name)
@@ -156,10 +143,6 @@ Gfx::PComputeCommand Graphics::createComputeCommand(const std::string& name)
return getComputeCommands()->createComputeCommand(name);
}
Gfx::OVertexDeclaration Graphics::createVertexDeclaration(const Array<Gfx::VertexElement>& element)
{
return new VertexDeclaration(element);
}
Gfx::OVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createInfo)
{
@@ -206,27 +189,29 @@ Gfx::PComputePipeline Graphics::createComputePipeline(Gfx::ComputePipelineCreate
return pipelineCache->createPipeline(std::move(createInfo));
}
Gfx::OSamplerState Graphics::createSamplerState(const SamplerCreateInfo& createInfo)
Gfx::OSampler Graphics::createSampler(const SamplerCreateInfo& createInfo)
{
OSamplerState sampler = new SamplerState();
VkSamplerCreateInfo vkInfo =
init::SamplerCreateInfo();
vkInfo.addressModeU = cast(createInfo.addressModeU);
vkInfo.addressModeV = cast(createInfo.addressModeV);
vkInfo.addressModeW = cast(createInfo.addressModeW);
vkInfo.anisotropyEnable = createInfo.anisotropyEnable;
vkInfo.borderColor = cast(createInfo.borderColor);
vkInfo.compareEnable = createInfo.compareEnable;
vkInfo.compareOp = cast(createInfo.compareOp);
vkInfo.flags = createInfo.flags;
vkInfo.magFilter = cast(createInfo.magFilter);
vkInfo.maxAnisotropy = createInfo.maxAnisotropy;
vkInfo.maxLod = createInfo.maxLod;
vkInfo.minFilter = cast(createInfo.minFilter);
vkInfo.minLod = createInfo.minLod;
vkInfo.mipLodBias = createInfo.mipLodBias;
vkInfo.mipmapMode = cast(createInfo.mipmapMode);
vkInfo.unnormalizedCoordinates = createInfo.unnormalizedCoordinates;
OSampler sampler = new Sampler();
VkSamplerCreateInfo vkInfo = {
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
.pNext = nullptr,
.flags = createInfo.flags,
.magFilter = cast(createInfo.magFilter),
.minFilter = cast(createInfo.minFilter),
.mipmapMode = cast(createInfo.mipmapMode),
.addressModeU = cast(createInfo.addressModeU),
.addressModeV = cast(createInfo.addressModeV),
.addressModeW = cast(createInfo.addressModeW),
.mipLodBias = createInfo.mipLodBias,
.anisotropyEnable = createInfo.anisotropyEnable,
.maxAnisotropy = createInfo.maxAnisotropy,
.compareEnable = createInfo.compareEnable,
.compareOp = cast(createInfo.compareOp),
.minLod = createInfo.minLod,
.maxLod = createInfo.maxLod,
.borderColor = cast(createInfo.borderColor),
.unnormalizedCoordinates = createInfo.unnormalizedCoordinates,
};
VK_CHECK(vkCreateSampler(handle, &vkInfo, nullptr, &sampler->sampler));
return sampler;
}
@@ -246,7 +231,7 @@ void Graphics::vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint
cmdDrawMeshTasks(handle, groupX, groupY, groupZ);
}
PCommandBufferManager Graphics::getQueueCommands(Gfx::QueueType queueType)
PCommandPool Graphics::getQueueCommands(Gfx::QueueType queueType)
{
switch (queueType)
{
@@ -262,7 +247,7 @@ PCommandBufferManager Graphics::getQueueCommands(Gfx::QueueType queueType)
throw new std::logic_error("invalid queue type");
}
}
PCommandBufferManager Graphics::getGraphicsCommands()
PCommandPool Graphics::getGraphicsCommands()
{
if(graphicsCommands == nullptr)
{
@@ -270,7 +255,7 @@ PCommandBufferManager Graphics::getGraphicsCommands()
}
return graphicsCommands;
}
PCommandBufferManager Graphics::getComputeCommands()
PCommandPool Graphics::getComputeCommands()
{
if(computeCommands == nullptr)
{
@@ -278,7 +263,7 @@ PCommandBufferManager Graphics::getComputeCommands()
}
return computeCommands;
}
PCommandBufferManager Graphics::getTransferCommands()
PCommandPool Graphics::getTransferCommands()
{
if(transferCommands == nullptr)
{
@@ -286,7 +271,7 @@ PCommandBufferManager Graphics::getTransferCommands()
}
return transferCommands;
}
PCommandBufferManager Graphics::getDedicatedTransferCommands()
PCommandPool Graphics::getDedicatedTransferCommands()
{
if(dedicatedTransferCommands == nullptr)
{
@@ -356,9 +341,13 @@ void Graphics::initInstance(GraphicsInitializer initInfo)
}
void Graphics::setupDebugCallback()
{
VkDebugReportCallbackCreateInfoEXT createInfo =
init::DebugReportCallbackCreateInfo(
VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT);
VkDebugReportCallbackCreateInfoEXT createInfo = {
.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
.pNext = nullptr,
.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT,
.pfnCallback = &debugCallback,
.pUserData = nullptr,
};
VK_CHECK(CreateDebugReportCallbackEXT(instance, &createInfo, nullptr, &callback));
}
@@ -488,8 +477,13 @@ void Graphics::createDevice(GraphicsInitializer initializer)
}
if (numQueuesForFamily > 0)
{
VkDeviceQueueCreateInfo info =
init::DeviceQueueCreateInfo(familyIndex, numQueuesForFamily);
VkDeviceQueueCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.queueFamilyIndex = familyIndex,
.queueCount = numQueuesForFamily,
};
numPriorities += numQueuesForFamily;
queueInfos.add(info);
}
@@ -507,11 +501,6 @@ void Graphics::createDevice(GraphicsInitializer initializer)
*currentPriority++ = 1.0f;
}
}
VkDeviceCreateInfo deviceInfo = init::DeviceCreateInfo(
queueInfos.data(),
(uint32)queueInfos.size(),
nullptr);
VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexing = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES,
.shaderSampledImageArrayNonUniformIndexing = VK_TRUE,
@@ -519,17 +508,6 @@ void Graphics::createDevice(GraphicsInitializer initializer)
.descriptorBindingVariableDescriptorCount = VK_TRUE,
.runtimeDescriptorArray = VK_TRUE,
};
deviceInfo.pNext = &descriptorIndexing;
#if ENABLE_VALIDATION
VkDeviceDiagnosticsConfigCreateInfoNV crashDiagInfo;
crashDiagInfo.sType = VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV;
crashDiagInfo.pNext = nullptr;
crashDiagInfo.flags =
VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_RESOURCE_TRACKING_BIT_NV |
VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_AUTOMATIC_CHECKPOINTS_BIT_NV |
VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_DEBUG_INFO_BIT_NV;
descriptorIndexing.pNext = &crashDiagInfo;
#endif
VkPhysicalDeviceMeshShaderFeaturesEXT enabledMeshShaderFeatures = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT,
.taskShader = VK_TRUE,
@@ -540,11 +518,17 @@ void Graphics::createDevice(GraphicsInitializer initializer)
descriptorIndexing.pNext = &enabledMeshShaderFeatures;
initializer.deviceExtensions.add("VK_EXT_mesh_shader");
}
deviceInfo.enabledExtensionCount = (uint32)initializer.deviceExtensions.size();
deviceInfo.ppEnabledExtensionNames = initializer.deviceExtensions.data();
deviceInfo.enabledLayerCount = (uint32_t)initializer.layers.size();
deviceInfo.ppEnabledLayerNames = initializer.layers.data();
deviceInfo.pEnabledFeatures = &features;
VkDeviceCreateInfo deviceInfo = {
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pNext = &descriptorIndexing,
.queueCreateInfoCount = (uint32)queueInfos.size(),
.pQueueCreateInfos = queueInfos.data(),
.enabledLayerCount = (uint32_t)initializer.layers.size(),
.ppEnabledLayerNames = initializer.layers.data(),
.enabledExtensionCount = (uint32)initializer.deviceExtensions.size(),
.ppEnabledExtensionNames = initializer.deviceExtensions.data(),
.pEnabledFeatures = &features,
};
VK_CHECK(vkCreateDevice(physicalDevice, &deviceInfo, nullptr, &handle));
std::cout << "Vulkan handle: " << handle << std::endl;
+11 -13
View File
@@ -12,6 +12,7 @@ DECLARE_REF(DestructionManager)
DECLARE_REF(CommandPool)
DECLARE_REF(Queue)
DECLARE_REF(PipelineCache)
DECLARE_REF(Framebuffer)
class Graphics : public Gfx::Graphics
{
public:
@@ -21,11 +22,11 @@ public:
constexpr VkDevice getDevice() const { return handle; };
constexpr VkPhysicalDevice getPhysicalDevice() const { return physicalDevice; };
PCommandBufferManager getQueueCommands(Gfx::QueueType queueType);
PCommandBufferManager getGraphicsCommands();
PCommandBufferManager getComputeCommands();
PCommandBufferManager getTransferCommands();
PCommandBufferManager getDedicatedTransferCommands();
PCommandPool getQueueCommands(Gfx::QueueType queueType);
PCommandPool getGraphicsCommands();
PCommandPool getComputeCommands();
PCommandPool getTransferCommands();
PCommandPool getDedicatedTransferCommands();
PAllocator getAllocator();
PStagingManager getStagingManager();
@@ -62,12 +63,11 @@ public:
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo) override;
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo) override;
virtual Gfx::PComputePipeline createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo) override;
virtual Gfx::OSampler createSamplerState(const SamplerCreateInfo& createInfo) override;
virtual Gfx::OSampler createSampler(const SamplerCreateInfo& createInfo) override;
virtual Gfx::ODescriptorLayout createDescriptorLayout(const std::string& name = "") override;
virtual Gfx::OPipelineLayout createPipelineLayout(Gfx::PPipelineLayout baseLayout = nullptr) override;
virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) override;
void vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint32 groupY, uint32 groupZ);
protected:
PFN_vkCmdDrawMeshTasksEXT cmdDrawMeshTasks;
@@ -86,15 +86,13 @@ protected:
OQueue transferQueue;
OQueue dedicatedTransferQueue;
OPipelineCache pipelineCache;
thread_local static OCommandBufferManager graphicsCommands;
thread_local static OCommandBufferManager computeCommands;
thread_local static OCommandBufferManager transferCommands;
thread_local static OCommandBufferManager dedicatedTransferCommands;
thread_local static OCommandPool graphicsCommands;
thread_local static OCommandPool computeCommands;
thread_local static OCommandPool transferCommands;
thread_local static OCommandPool dedicatedTransferCommands;
VkPhysicalDeviceProperties props;
VkPhysicalDeviceFeatures features;
VkDebugReportCallbackEXT callback;
Array<PViewport> viewports;
std::mutex allocatedFrameBufferLock;
Map<uint32, OFramebuffer> allocatedFramebuffers;
OAllocator allocator;
OStagingManager stagingManager;
-807
View File
@@ -1,807 +0,0 @@
#include "Initializer.h"
#include <iostream>
#include "Initializer.h"
#include "Initializer.h"
using namespace Seele::Vulkan;
VkApplicationInfo init::ApplicationInfo(const char *appName, uint32_t appVersion, const char *engineName, uint32_t engineVersion, uint32_t apiVersion)
{
VkApplicationInfo info = {};
info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
info.pApplicationName = appName;
info.applicationVersion = appVersion;
info.pEngineName = engineName;
info.engineVersion = engineVersion;
info.apiVersion = apiVersion;
return info;
}
VkInstanceCreateInfo init::InstanceCreateInfo(VkApplicationInfo *appInfo, const Array<const char *> &extensions, const Array<const char *> &layers)
{
VkInstanceCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
info.pApplicationInfo = appInfo;
info.enabledExtensionCount = (uint32_t)extensions.size();
info.ppEnabledExtensionNames = extensions.data();
info.enabledLayerCount = (uint32_t)layers.size();
info.ppEnabledLayerNames = layers.data();
return info;
}
VkDebugReportCallbackCreateInfoEXT init::DebugReportCallbackCreateInfo(VkDebugReportFlagsEXT flags)
{
VkDebugReportCallbackCreateInfoEXT createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
createInfo.flags = flags;
createInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT)debugCallback;
return createInfo;
}
VkDeviceQueueCreateInfo init::DeviceQueueCreateInfo(int queueFamilyIndex, int queueCount)
{
float priority = 1.0f;
return DeviceQueueCreateInfo(queueFamilyIndex, queueCount, &priority);
}
VkDeviceQueueCreateInfo init::DeviceQueueCreateInfo(int queueFamilyIndex, int queueCount, float *queuePriority)
{
VkDeviceQueueCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
createInfo.queueFamilyIndex = queueFamilyIndex;
createInfo.queueCount = queueCount;
createInfo.pQueuePriorities = queuePriority;
return createInfo;
}
VkDeviceCreateInfo init::DeviceCreateInfo(VkDeviceQueueCreateInfo *queueInfos, uint32_t queueCount, VkPhysicalDeviceFeatures *features)
{
return DeviceCreateInfo(queueInfos, queueCount, features, nullptr, 0, nullptr, 0);
}
VkSwapchainCreateInfoKHR init::SwapchainCreateInfo(VkSurfaceKHR surface, uint32_t minImageCount, VkFormat imageFormat, VkColorSpaceKHR colorSpace, VkExtent2D extent, uint32_t arrayLayers, VkImageUsageFlags usage, VkSurfaceTransformFlagBitsKHR Transform, VkCompositeAlphaFlagBitsKHR alpha, VkPresentModeKHR presentMode, VkBool32 clipped)
{
VkSwapchainCreateInfoKHR createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
createInfo.surface = surface;
createInfo.minImageCount = minImageCount;
createInfo.imageFormat = imageFormat;
createInfo.imageColorSpace = colorSpace;
createInfo.imageExtent = extent;
createInfo.imageArrayLayers = arrayLayers;
createInfo.imageUsage = usage;
createInfo.preTransform = Transform;
createInfo.compositeAlpha = alpha;
createInfo.presentMode = presentMode;
createInfo.clipped = clipped;
return createInfo;
}
VkSwapchainCreateInfoKHR init::SwapchainCreateInfo(VkSurfaceKHR surface, uint32_t minImageCount, VkFormat imageFormat, VkColorSpaceKHR colorSpace, uint32_t width, uint32_t height, uint32_t arrayLayers, VkImageUsageFlags usage, VkSurfaceTransformFlagBitsKHR Transform, VkCompositeAlphaFlagBitsKHR alpha, VkPresentModeKHR presentMode, VkBool32 clipped)
{
VkSwapchainCreateInfoKHR createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
createInfo.surface = surface;
createInfo.minImageCount = minImageCount;
createInfo.imageFormat = imageFormat;
createInfo.imageColorSpace = colorSpace;
createInfo.imageExtent.width = width;
createInfo.imageExtent.height = height;
createInfo.imageArrayLayers = arrayLayers;
createInfo.imageUsage = usage;
createInfo.preTransform = Transform;
createInfo.compositeAlpha = alpha;
createInfo.presentMode = presentMode;
createInfo.clipped = clipped;
return createInfo;
}
VkFramebufferCreateInfo init::FramebufferCreateInfo(VkRenderPass renderPass, uint32_t attachmentCount, VkImageView *attachments, uint32_t width, uint32_t height, uint32_t layers)
{
VkFramebufferCreateInfo frameBufferCreateInfo = {};
frameBufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
frameBufferCreateInfo.pNext = nullptr;
frameBufferCreateInfo.renderPass = renderPass;
frameBufferCreateInfo.attachmentCount = attachmentCount;
frameBufferCreateInfo.pAttachments = attachments;
frameBufferCreateInfo.width = width;
frameBufferCreateInfo.height = height;
frameBufferCreateInfo.layers = layers;
return frameBufferCreateInfo;
}
VkAttachmentDescription init::AttachmentDescription(VkFormat format, VkSampleCountFlagBits sample, VkAttachmentLoadOp loadOp, VkAttachmentStoreOp storeOp, VkAttachmentLoadOp stencilLoadOp, VkAttachmentStoreOp stencilStoreOp, VkImageLayout imageLayout, VkImageLayout finalLayout)
{
VkAttachmentDescription desc = {};
desc.format = format;
desc.samples = sample;
desc.loadOp = loadOp;
desc.storeOp = storeOp;
desc.stencilLoadOp = stencilLoadOp;
desc.stencilStoreOp = stencilStoreOp;
desc.initialLayout = imageLayout;
desc.finalLayout = finalLayout;
return desc;
}
VkSubpassDescription init::SubpassDescription(VkPipelineBindPoint bindPoint,
uint32_t colorAttachmentCount, VkAttachmentReference *colorReference,
VkAttachmentReference *depthReference,
uint32_t inputAttachmentCount, VkAttachmentReference *inputReference,
VkAttachmentReference *resolveReference, uint32_t preserveAttachmentCount, uint32_t *preserveReference)
{
VkSubpassDescription desc = {};
desc.pipelineBindPoint = bindPoint;
desc.colorAttachmentCount = colorAttachmentCount;
desc.pColorAttachments = colorReference;
desc.inputAttachmentCount = inputAttachmentCount;
desc.pInputAttachments = inputReference;
desc.pResolveAttachments = resolveReference;
desc.preserveAttachmentCount = preserveAttachmentCount;
desc.pPreserveAttachments = preserveReference;
desc.pDepthStencilAttachment = depthReference;
return desc;
}
VkRenderPassCreateInfo init::RenderPassCreateInfo(uint32_t attachmentCount, const VkAttachmentDescription *attachments, uint32_t subpassCount, const VkSubpassDescription *subpasses, uint32_t dependencyCount, const VkSubpassDependency *subpassDependencies)
{
VkRenderPassCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
info.attachmentCount = attachmentCount;
info.pAttachments = attachments;
info.subpassCount = subpassCount;
info.pSubpasses = subpasses;
info.dependencyCount = dependencyCount;
info.pDependencies = subpassDependencies;
return info;
}
VkDeviceCreateInfo init::DeviceCreateInfo(VkDeviceQueueCreateInfo *queueInfos, uint32_t queueCount, VkPhysicalDeviceFeatures *features, const char *const *deviceExtensions, uint32_t deviceExtensionCount, const char *const *layers, uint32_t layerCount)
{
VkDeviceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
createInfo.pQueueCreateInfos = queueInfos;
createInfo.queueCreateInfoCount = queueCount;
createInfo.pEnabledFeatures = features;
createInfo.ppEnabledExtensionNames = deviceExtensions;
createInfo.enabledExtensionCount = deviceExtensionCount;
#ifdef ENABLE_VALIDATION
createInfo.enabledLayerCount = layerCount;
createInfo.ppEnabledLayerNames = layers;
#else
(void)layers;
(void)layerCount;
createInfo.enabledLayerCount = 0;
layerCount = 0;
layers = nullptr;
#endif // ENABLE_VALIDATION
return createInfo;
}
VkMemoryAllocateInfo init::MemoryAllocateInfo()
{
VkMemoryAllocateInfo memAllocInfo = {};
memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memAllocInfo.pNext = NULL;
return memAllocInfo;
}
VkCommandBufferAllocateInfo init::CommandBufferAllocateInfo(VkCommandPool commandPool, VkCommandBufferLevel level, uint32_t bufferCount)
{
VkCommandBufferAllocateInfo commandBufferAllocateInfo = {};
commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
commandBufferAllocateInfo.commandPool = commandPool;
commandBufferAllocateInfo.level = level;
commandBufferAllocateInfo.commandBufferCount = bufferCount;
return commandBufferAllocateInfo;
}
VkCommandPoolCreateInfo init::CommandPoolCreateInfo()
{
VkCommandPoolCreateInfo cmdPoolCreateInfo = {};
cmdPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
return cmdPoolCreateInfo;
}
VkCommandBufferBeginInfo init::CommandBufferBeginInfo()
{
VkCommandBufferBeginInfo cmdBufferBeginInfo = {};
cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
cmdBufferBeginInfo.pNext = NULL;
return cmdBufferBeginInfo;
}
VkCommandBufferInheritanceInfo init::CommandBufferInheritanceInfo()
{
VkCommandBufferInheritanceInfo cmdBufferInheritanceInfo = {};
cmdBufferInheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
return cmdBufferInheritanceInfo;
}
VkRenderPassBeginInfo init::RenderPassBeginInfo()
{
VkRenderPassBeginInfo renderPassBeginInfo = {};
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassBeginInfo.pNext = NULL;
return renderPassBeginInfo;
}
VkRenderPassCreateInfo init::RenderPassCreateInfo()
{
VkRenderPassCreateInfo renderPassCreateInfo = {};
renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassCreateInfo.pNext = NULL;
return renderPassCreateInfo;
}
VkImageMemoryBarrier init::ImageMemoryBarrier(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, uint32_t srcQueue, uint32_t dstQueue)
{
VkImageMemoryBarrier barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.oldLayout = oldLayout;
barrier.newLayout = newLayout;
barrier.srcQueueFamilyIndex = srcQueue;
barrier.dstQueueFamilyIndex = dstQueue;
barrier.image = image;
if (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
{
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
}
else
{
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
}
barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.levelCount = 1;
barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.layerCount = 1;
if (oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
{
barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
}
else if (oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
{
barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
}
else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
{
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
}
else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
{
barrier.srcAccessMask = 0;
barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
}
else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
{
barrier.srcAccessMask = 0;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
}
return barrier;
}
VkImageMemoryBarrier init::ImageMemoryBarrier()
{
VkImageMemoryBarrier barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.pNext = nullptr;
return barrier;
}
VkBufferMemoryBarrier init::BufferMemoryBarrier()
{
VkBufferMemoryBarrier bufferMemoryBarrier = {};
bufferMemoryBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
bufferMemoryBarrier.pNext = NULL;
bufferMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufferMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
return bufferMemoryBarrier;
}
VkMemoryBarrier init::MemoryBarrier()
{
VkMemoryBarrier memoryBarrier = {};
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.pNext = NULL;
return memoryBarrier;
}
VkImageCreateInfo init::ImageCreateInfo()
{
VkImageCreateInfo imageCreateInfo = {};
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageCreateInfo.pNext = NULL;
return imageCreateInfo;
}
VkSamplerCreateInfo init::SamplerCreateInfo()
{
VkSamplerCreateInfo samplerCreateInfo = {};
samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
samplerCreateInfo.pNext = NULL;
samplerCreateInfo.magFilter = VK_FILTER_LINEAR;
samplerCreateInfo.minFilter = VK_FILTER_LINEAR;
samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerCreateInfo.anisotropyEnable = VK_FALSE;
samplerCreateInfo.maxAnisotropy = 1.0f;
samplerCreateInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
samplerCreateInfo.unnormalizedCoordinates = VK_FALSE;
samplerCreateInfo.compareEnable = VK_FALSE;
samplerCreateInfo.compareOp = VK_COMPARE_OP_ALWAYS;
samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
samplerCreateInfo.mipLodBias = 0.0f;
samplerCreateInfo.minLod = 0.0f;
samplerCreateInfo.maxLod = 0.0f;
return samplerCreateInfo;
}
VkImageViewCreateInfo init::ImageViewCreateInfo()
{
VkImageViewCreateInfo imageViewCreateInfo = {};
imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
imageViewCreateInfo.pNext = NULL;
return imageViewCreateInfo;
}
VkSemaphoreCreateInfo init::SemaphoreCreateInfo()
{
VkSemaphoreCreateInfo semaphoreCreateInfo = {};
semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
semaphoreCreateInfo.pNext = NULL;
semaphoreCreateInfo.flags = 0;
return semaphoreCreateInfo;
}
VkFenceCreateInfo init::FenceCreateInfo(VkFenceCreateFlags flags)
{
VkFenceCreateInfo fenceCreateInfo = {};
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceCreateInfo.flags = flags;
return fenceCreateInfo;
}
VkEventCreateInfo init::EventCreateInfo()
{
VkEventCreateInfo eventCreateInfo = {};
eventCreateInfo.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
return eventCreateInfo;
}
VkSubmitInfo init::SubmitInfo()
{
VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.pNext = NULL;
return submitInfo;
}
VkImageSubresourceRange init::ImageSubresourceRange(VkImageAspectFlags aspect, uint32_t startMip)
{
VkImageSubresourceRange range;
std::memset(&range, 0, sizeof(VkImageSubresourceRange));
range.aspectMask = aspect;
range.baseMipLevel = startMip;
range.levelCount = 1;
range.baseArrayLayer = 0;
range.layerCount = 1;
return range;
}
VkViewport init::Viewport(
float width,
float height,
float minDepth,
float maxDepth)
{
VkViewport viewport = {};
viewport.width = width;
viewport.height = height;
viewport.minDepth = minDepth;
viewport.maxDepth = maxDepth;
return viewport;
}
VkRect2D init::Rect2D(
int32_t width,
int32_t height,
int32_t offsetX,
int32_t offsetY)
{
VkRect2D rect2D = {};
rect2D.extent.width = width;
rect2D.extent.height = height;
rect2D.offset.x = offsetX;
rect2D.offset.y = offsetY;
return rect2D;
}
VkBufferCreateInfo init::BufferCreateInfo()
{
VkBufferCreateInfo bufCreateInfo = {};
bufCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
return bufCreateInfo;
}
VkBufferCreateInfo init::BufferCreateInfo(
VkBufferUsageFlags usage,
VkDeviceSize size)
{
VkBufferCreateInfo bufCreateInfo = {};
bufCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufCreateInfo.pNext = NULL;
bufCreateInfo.usage = usage;
bufCreateInfo.size = size;
bufCreateInfo.flags = 0;
return bufCreateInfo;
}
VkDescriptorPoolCreateInfo init::DescriptorPoolCreateInfo(
uint32_t poolSizeCount,
VkDescriptorPoolSize *pPoolSizes,
uint32_t maxSets)
{
VkDescriptorPoolCreateInfo descriptorPoolInfo = {};
descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptorPoolInfo.pNext = NULL;
descriptorPoolInfo.poolSizeCount = poolSizeCount;
descriptorPoolInfo.pPoolSizes = pPoolSizes;
descriptorPoolInfo.maxSets = maxSets;
return descriptorPoolInfo;
}
VkDescriptorPoolSize init::DescriptorPoolSize(
VkDescriptorType type,
uint32_t descriptorCount)
{
VkDescriptorPoolSize descriptorPoolSize = {};
descriptorPoolSize.type = type;
descriptorPoolSize.descriptorCount = descriptorCount;
return descriptorPoolSize;
}
VkDescriptorSetLayoutBinding init::DescriptorSetLayoutBinding(
VkDescriptorType type,
VkShaderStageFlags stageFlags,
uint32_t binding,
uint32_t count)
{
VkDescriptorSetLayoutBinding setLayoutBinding = {};
setLayoutBinding.descriptorType = type;
setLayoutBinding.stageFlags = stageFlags;
setLayoutBinding.binding = binding;
setLayoutBinding.descriptorCount = count;
return setLayoutBinding;
}
VkDescriptorSetLayoutCreateInfo init::DescriptorSetLayoutCreateInfo(
const VkDescriptorSetLayoutBinding *pBindings,
uint32_t bindingCount)
{
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {};
descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
descriptorSetLayoutCreateInfo.pNext = NULL;
descriptorSetLayoutCreateInfo.pBindings = pBindings;
descriptorSetLayoutCreateInfo.bindingCount = bindingCount;
return descriptorSetLayoutCreateInfo;
}
VkPipelineLayoutCreateInfo init::PipelineLayoutCreateInfo(
const VkDescriptorSetLayout *pSetLayouts,
uint32_t setLayoutCount)
{
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {};
pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutCreateInfo.pNext = NULL;
pipelineLayoutCreateInfo.setLayoutCount = setLayoutCount;
pipelineLayoutCreateInfo.pSetLayouts = pSetLayouts;
return pipelineLayoutCreateInfo;
}
VkDescriptorSetAllocateInfo init::DescriptorSetAllocateInfo(
VkDescriptorPool descriptorPool,
const VkDescriptorSetLayout *pSetLayouts,
uint32_t descriptorSetCount)
{
VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {};
descriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
descriptorSetAllocateInfo.pNext = NULL;
descriptorSetAllocateInfo.descriptorPool = descriptorPool;
descriptorSetAllocateInfo.pSetLayouts = pSetLayouts;
descriptorSetAllocateInfo.descriptorSetCount = descriptorSetCount;
return descriptorSetAllocateInfo;
}
VkDescriptorBufferInfo init::DescriptorBufferInfo(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range)
{
VkDescriptorBufferInfo bufferInfo = {};
bufferInfo.buffer = buffer;
bufferInfo.offset = offset;
bufferInfo.range = range;
return bufferInfo;
}
VkDescriptorImageInfo init::DescriptorImageInfo(
VkSampler sampler,
VkImageView imageView,
VkImageLayout imageLayout)
{
VkDescriptorImageInfo descriptorImageInfo = {};
descriptorImageInfo.sampler = sampler;
descriptorImageInfo.imageView = imageView;
descriptorImageInfo.imageLayout = imageLayout;
return descriptorImageInfo;
}
VkWriteDescriptorSet init::WriteDescriptorSet(
VkDescriptorSet dstSet,
VkDescriptorType type,
uint32_t binding,
VkDescriptorBufferInfo *bufferInfo)
{
VkWriteDescriptorSet writeDescriptorSet = {};
writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeDescriptorSet.pNext = NULL;
writeDescriptorSet.dstSet = dstSet;
writeDescriptorSet.descriptorType = type;
writeDescriptorSet.dstBinding = binding;
writeDescriptorSet.pBufferInfo = bufferInfo;
// Default value in all examples
writeDescriptorSet.descriptorCount = 1;
return writeDescriptorSet;
}
VkWriteDescriptorSet init::WriteDescriptorSet(
VkDescriptorSet dstSet,
VkDescriptorType type,
uint32_t binding,
VkDescriptorImageInfo *bufferInfo)
{
VkWriteDescriptorSet writeDescriptorSet = {};
writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeDescriptorSet.pNext = NULL;
writeDescriptorSet.dstSet = dstSet;
writeDescriptorSet.descriptorType = type;
writeDescriptorSet.dstBinding = binding;
writeDescriptorSet.pImageInfo = bufferInfo;
// Default value in all examples
writeDescriptorSet.descriptorCount = 1;
return writeDescriptorSet;
}
VkVertexInputBindingDescription init::VertexInputBindingDescription(
uint32_t binding,
uint32_t stride,
VkVertexInputRate inputRate)
{
VkVertexInputBindingDescription vInputBindDescription = {};
vInputBindDescription.binding = binding;
vInputBindDescription.stride = stride;
vInputBindDescription.inputRate = inputRate;
return vInputBindDescription;
}
VkVertexInputAttributeDescription init::VertexInputAttributeDescription(
uint32_t binding,
uint32_t location,
VkFormat format,
uint32_t offset)
{
VkVertexInputAttributeDescription vInputAttribDescription = {};
vInputAttribDescription.location = location;
vInputAttribDescription.binding = binding;
vInputAttribDescription.format = format;
vInputAttribDescription.offset = offset;
return vInputAttribDescription;
}
VkPipelineVertexInputStateCreateInfo init::PipelineVertexInputStateCreateInfo()
{
VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo = {};
pipelineVertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
pipelineVertexInputStateCreateInfo.pNext = NULL;
return pipelineVertexInputStateCreateInfo;
}
VkPipelineInputAssemblyStateCreateInfo init::PipelineInputAssemblyStateCreateInfo(
VkPrimitiveTopology topology,
VkPipelineInputAssemblyStateCreateFlags flags,
VkBool32 primitiveRestartEnable)
{
VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo = {};
pipelineInputAssemblyStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
pipelineInputAssemblyStateCreateInfo.topology = topology;
pipelineInputAssemblyStateCreateInfo.flags = flags;
pipelineInputAssemblyStateCreateInfo.primitiveRestartEnable = primitiveRestartEnable;
return pipelineInputAssemblyStateCreateInfo;
}
VkPipelineRasterizationStateCreateInfo init::PipelineRasterizationStateCreateInfo(
VkPolygonMode polygonMode,
VkCullModeFlags cullMode,
VkFrontFace frontFace,
VkPipelineRasterizationStateCreateFlags flags)
{
VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateCreateInfo = {};
pipelineRasterizationStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
pipelineRasterizationStateCreateInfo.polygonMode = polygonMode;
pipelineRasterizationStateCreateInfo.cullMode = cullMode;
pipelineRasterizationStateCreateInfo.frontFace = frontFace;
pipelineRasterizationStateCreateInfo.flags = flags;
pipelineRasterizationStateCreateInfo.depthClampEnable = VK_FALSE;
pipelineRasterizationStateCreateInfo.lineWidth = 1.0f;
return pipelineRasterizationStateCreateInfo;
}
VkPipelineColorBlendAttachmentState init::PipelineColorBlendAttachmentState(
VkColorComponentFlags colorWriteMask,
VkBool32 blendEnable)
{
VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState = {};
pipelineColorBlendAttachmentState.colorWriteMask = colorWriteMask;
pipelineColorBlendAttachmentState.blendEnable = blendEnable;
return pipelineColorBlendAttachmentState;
}
VkPipelineColorBlendStateCreateInfo init::PipelineColorBlendStateCreateInfo(
uint32_t attachmentCount,
const VkPipelineColorBlendAttachmentState *pAttachments)
{
VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo = {};
pipelineColorBlendStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
pipelineColorBlendStateCreateInfo.pNext = NULL;
pipelineColorBlendStateCreateInfo.attachmentCount = attachmentCount;
pipelineColorBlendStateCreateInfo.pAttachments = pAttachments;
return pipelineColorBlendStateCreateInfo;
}
VkPipelineDepthStencilStateCreateInfo init::PipelineDepthStencilStateCreateInfo(
VkBool32 depthTestEnable,
VkBool32 depthWriteEnable,
VkCompareOp depthCompareOp)
{
VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateCreateInfo = {};
pipelineDepthStencilStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
pipelineDepthStencilStateCreateInfo.depthTestEnable = depthTestEnable;
pipelineDepthStencilStateCreateInfo.depthWriteEnable = depthWriteEnable;
pipelineDepthStencilStateCreateInfo.depthCompareOp = depthCompareOp;
pipelineDepthStencilStateCreateInfo.front = pipelineDepthStencilStateCreateInfo.back;
pipelineDepthStencilStateCreateInfo.back.compareOp = VK_COMPARE_OP_ALWAYS;
return pipelineDepthStencilStateCreateInfo;
}
VkPipelineViewportStateCreateInfo init::PipelineViewportStateCreateInfo(
uint32_t viewportCount,
uint32_t scissorCount,
VkPipelineViewportStateCreateFlags flags)
{
VkPipelineViewportStateCreateInfo pipelineViewportStateCreateInfo = {};
pipelineViewportStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
pipelineViewportStateCreateInfo.viewportCount = viewportCount;
pipelineViewportStateCreateInfo.scissorCount = scissorCount;
pipelineViewportStateCreateInfo.flags = flags;
return pipelineViewportStateCreateInfo;
}
VkPipelineMultisampleStateCreateInfo init::PipelineMultisampleStateCreateInfo(
VkSampleCountFlagBits rasterizationSamples,
VkPipelineMultisampleStateCreateFlags flags)
{
VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo = {};
pipelineMultisampleStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
pipelineMultisampleStateCreateInfo.flags = flags;
pipelineMultisampleStateCreateInfo.rasterizationSamples = rasterizationSamples;
return pipelineMultisampleStateCreateInfo;
}
VkPipelineDynamicStateCreateInfo init::PipelineDynamicStateCreateInfo(
const VkDynamicState *pDynamicStates,
uint32_t dynamicStateCount,
VkPipelineDynamicStateCreateFlags flags)
{
VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {};
pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
pipelineDynamicStateCreateInfo.flags = flags;
pipelineDynamicStateCreateInfo.pDynamicStates = pDynamicStates;
pipelineDynamicStateCreateInfo.dynamicStateCount = dynamicStateCount;
return pipelineDynamicStateCreateInfo;
}
VkPipelineTessellationStateCreateInfo init::PipelineTessellationStateCreateInfo(uint32_t patchControlPoints)
{
VkPipelineTessellationStateCreateInfo pipelineTessellationStateCreateInfo = {};
pipelineTessellationStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
pipelineTessellationStateCreateInfo.patchControlPoints = patchControlPoints;
return pipelineTessellationStateCreateInfo;
}
VkGraphicsPipelineCreateInfo init::PipelineCreateInfo(
VkPipelineLayout layout,
VkRenderPass renderPass,
VkPipelineCreateFlags flags)
{
VkGraphicsPipelineCreateInfo pipelineCreateInfo = {};
pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipelineCreateInfo.pNext = NULL;
pipelineCreateInfo.layout = layout;
pipelineCreateInfo.renderPass = renderPass;
pipelineCreateInfo.flags = flags;
return pipelineCreateInfo;
}
VkComputePipelineCreateInfo init::ComputePipelineCreateInfo(VkPipelineLayout layout, VkPipelineCreateFlags flags)
{
VkComputePipelineCreateInfo computePipelineCreateInfo = {};
computePipelineCreateInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
computePipelineCreateInfo.layout = layout;
computePipelineCreateInfo.flags = flags;
return computePipelineCreateInfo;
}
VkPushConstantRange init::PushConstantRange(
VkShaderStageFlags stageFlags,
uint32_t size,
uint32_t offset)
{
VkPushConstantRange pushConstantRange = {};
pushConstantRange.stageFlags = stageFlags;
pushConstantRange.offset = offset;
pushConstantRange.size = size;
return pushConstantRange;
}
VkPipelineShaderStageCreateInfo init::PipelineShaderStageCreateInfo(VkShaderStageFlagBits stage, VkShaderModule module, const char *entryName)
{
VkPipelineShaderStageCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
info.module = module;
info.stage = stage;
info.pName = entryName;
return info;
}
VkBool32 Seele::Vulkan::debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT, uint64_t, size_t, int32_t, const char *layerPrefix, const char *msg, void *)
{
if(flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)
{
return VK_FALSE;
}
else
{
std::cerr << layerPrefix << ": " << msg << std::endl;
return VK_FALSE;
}
}
VkResult Seele::Vulkan::CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback)
{
auto func = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");
if (func != nullptr)
{
return func(instance, pCreateInfo, pAllocator, pCallback);
}
else
{
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
}
void Seele::Vulkan::DestroyDebugReportCallbackEXT(VkInstance instance, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT pCallback)
{
auto func = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT");
if (func != nullptr)
{
func(instance, pCallback, pAllocator);
}
}
-302
View File
@@ -1,302 +0,0 @@
#pragma once
#include "Containers/Array.h"
#include <vulkan/vulkan.h>
namespace Seele
{
namespace Vulkan
{
VkBool32 debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char *layerPrefix, const char *msg, void *userData);
VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback);
void DestroyDebugReportCallbackEXT(VkInstance instance, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT pCallback);
namespace init
{
VkApplicationInfo ApplicationInfo(
const char *appName,
uint32_t appVersion,
const char *engineName,
uint32_t engineVersion,
uint32_t apiVersion);
VkInstanceCreateInfo InstanceCreateInfo(
VkApplicationInfo *appInfo,
const Array<const char *> &extensions,
const Array<const char *> &layers);
VkDebugReportCallbackCreateInfoEXT DebugReportCallbackCreateInfo(
VkDebugReportFlagsEXT flags);
VkDeviceQueueCreateInfo DeviceQueueCreateInfo(
int queueFamilyIndex,
int queueCount);
VkDeviceQueueCreateInfo DeviceQueueCreateInfo(
int queueFamilyIndex,
int queueCount,
float *queuePriority);
VkDeviceCreateInfo DeviceCreateInfo(
VkDeviceQueueCreateInfo *queueInfos,
uint32_t queueCount,
VkPhysicalDeviceFeatures *features,
const char *const *deviceExtensions,
uint32_t deviceExtensionCount,
const char *const *layers,
uint32_t layerCount);
VkDeviceCreateInfo DeviceCreateInfo(
VkDeviceQueueCreateInfo *queueInfos,
uint32_t queueCount,
VkPhysicalDeviceFeatures *features);
VkSwapchainCreateInfoKHR SwapchainCreateInfo(
VkSurfaceKHR surface,
uint32_t minImageCount,
VkFormat imageFormat,
VkColorSpaceKHR colorSpace,
VkExtent2D extent,
uint32_t arrayLayers,
VkImageUsageFlags usage,
VkSurfaceTransformFlagBitsKHR Transform,
VkCompositeAlphaFlagBitsKHR alpha,
VkPresentModeKHR presentMode,
VkBool32 clipped);
VkSwapchainCreateInfoKHR SwapchainCreateInfo(
VkSurfaceKHR surface,
uint32_t minImageCount,
VkFormat imageFormat,
VkColorSpaceKHR colorSpace,
uint32_t width,
uint32_t height,
uint32_t arrayLayers,
VkImageUsageFlags usage,
VkSurfaceTransformFlagBitsKHR Transform,
VkCompositeAlphaFlagBitsKHR alpha,
VkPresentModeKHR presentMode,
VkBool32 clipped);
VkFramebufferCreateInfo FramebufferCreateInfo(
VkRenderPass renderPass,
uint32_t attachmentCount,
VkImageView *attachments,
uint32_t width,
uint32_t height,
uint32_t layers);
VkAttachmentDescription AttachmentDescription(
VkFormat format,
VkSampleCountFlagBits sample,
VkAttachmentLoadOp loadOp,
VkAttachmentStoreOp storeOp,
VkAttachmentLoadOp stencilLoadOp,
VkAttachmentStoreOp stencilStoreOp,
VkImageLayout imageLayout,
VkImageLayout finalLayout);
VkSubpassDescription SubpassDescription(
VkPipelineBindPoint bindPoint,
uint32_t colorAttachmentCount,
VkAttachmentReference *colorReference,
VkAttachmentReference *depthReference = nullptr,
uint32_t inputAttachmentCount = 0,
VkAttachmentReference *inputReference = nullptr,
VkAttachmentReference *resolveReference = nullptr,
uint32_t preserveAttachmentCount = 0,
uint32_t *preserveReference = nullptr);
VkRenderPassCreateInfo RenderPassCreateInfo(
uint32_t attachmentCount,
const VkAttachmentDescription *attachments,
uint32_t subpassCount,
const VkSubpassDescription *subpasses,
uint32_t dependencyCount,
const VkSubpassDependency *subpassDependencies);
VkMemoryAllocateInfo MemoryAllocateInfo();
VkCommandBufferAllocateInfo CommandBufferAllocateInfo(
VkCommandPool cmdPool,
VkCommandBufferLevel level,
uint32_t bufferCount);
VkCommandPoolCreateInfo CommandPoolCreateInfo();
VkCommandBufferBeginInfo CommandBufferBeginInfo();
VkCommandBufferInheritanceInfo CommandBufferInheritanceInfo();
VkRenderPassBeginInfo RenderPassBeginInfo();
VkRenderPassCreateInfo RenderPassCreateInfo();
VkImageMemoryBarrier ImageMemoryBarrier(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, uint32_t srcQueue = VK_QUEUE_FAMILY_IGNORED, uint32_t dstQueue = VK_QUEUE_FAMILY_IGNORED);
VkImageMemoryBarrier ImageMemoryBarrier();
VkBufferMemoryBarrier BufferMemoryBarrier();
VkMemoryBarrier MemoryBarrier();
VkImageCreateInfo ImageCreateInfo();
VkSamplerCreateInfo SamplerCreateInfo();
VkImageViewCreateInfo ImageViewCreateInfo();
VkSemaphoreCreateInfo SemaphoreCreateInfo();
VkFenceCreateInfo FenceCreateInfo(
VkFenceCreateFlags flags);
VkEventCreateInfo EventCreateInfo();
VkSubmitInfo SubmitInfo();
VkImageSubresourceRange ImageSubresourceRange(
VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT,
uint32_t startMip = 0);
VkViewport Viewport(
float width,
float height,
float minDepth,
float maxDepth);
VkRect2D Rect2D(
int32_t width,
int32_t height,
int32_t offsetX,
int32_t offsetY);
VkBufferCreateInfo BufferCreateInfo();
VkBufferCreateInfo BufferCreateInfo(
VkBufferUsageFlags usage,
VkDeviceSize size);
VkDescriptorPoolCreateInfo DescriptorPoolCreateInfo(
uint32_t poolSizeCount,
VkDescriptorPoolSize *pPoolSizes,
uint32_t maxSets);
VkDescriptorPoolSize DescriptorPoolSize(
VkDescriptorType type,
uint32_t descriptorCount);
VkDescriptorSetLayoutBinding DescriptorSetLayoutBinding(
VkDescriptorType type,
VkShaderStageFlags stageFlags,
uint32_t binding,
uint32_t count);
VkDescriptorSetLayoutCreateInfo DescriptorSetLayoutCreateInfo(
const VkDescriptorSetLayoutBinding *pBindings,
uint32_t bindingCount);
VkPipelineLayoutCreateInfo PipelineLayoutCreateInfo(
const VkDescriptorSetLayout *pSetLayouts,
uint32_t setLayoutCount);
VkDescriptorSetAllocateInfo DescriptorSetAllocateInfo(
VkDescriptorPool descriptorPool,
const VkDescriptorSetLayout *pSetLayouts,
uint32_t descriptorSetCount);
VkDescriptorBufferInfo DescriptorBufferInfo(
VkBuffer buffer,
VkDeviceSize offset,
VkDeviceSize range);
VkDescriptorImageInfo DescriptorImageInfo(
VkSampler sampler,
VkImageView imageView,
VkImageLayout imageLayout);
VkWriteDescriptorSet WriteDescriptorSet(
VkDescriptorSet dstSet,
VkDescriptorType type,
uint32_t binding,
VkDescriptorBufferInfo *bufferInfo);
VkWriteDescriptorSet WriteDescriptorSet(
VkDescriptorSet dstSet,
VkDescriptorType type,
uint32_t binding,
VkDescriptorImageInfo *bufferInfo);
VkVertexInputBindingDescription VertexInputBindingDescription(
uint32_t binding,
uint32_t stride,
VkVertexInputRate inputRate);
VkVertexInputAttributeDescription VertexInputAttributeDescription(
uint32_t binding,
uint32_t location,
VkFormat format,
uint32_t offset);
VkPipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo();
VkPipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo(
VkPrimitiveTopology topology,
VkPipelineInputAssemblyStateCreateFlags flags,
VkBool32 primitiveRestartEnable);
VkPipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo(
VkPolygonMode polygonMode,
VkCullModeFlags cullMode,
VkFrontFace frontFace,
VkPipelineRasterizationStateCreateFlags flags);
VkPipelineColorBlendAttachmentState PipelineColorBlendAttachmentState(
VkColorComponentFlags colorWriteMask,
VkBool32 blendEnable);
VkPipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo(
uint32_t attachmentCount,
const VkPipelineColorBlendAttachmentState *pAttachments);
VkPipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo(
VkBool32 depthTestEnable,
VkBool32 depthWriteEnable,
VkCompareOp depthCompareOp);
VkPipelineViewportStateCreateInfo PipelineViewportStateCreateInfo(
uint32_t viewportCount,
uint32_t scissorCount,
VkPipelineViewportStateCreateFlags flags);
VkPipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo(
VkSampleCountFlagBits rasterizationSamples,
VkPipelineMultisampleStateCreateFlags flags);
VkPipelineDynamicStateCreateInfo PipelineDynamicStateCreateInfo(
const VkDynamicState *pDynamicStates,
uint32_t dynamicStateCount,
VkPipelineDynamicStateCreateFlags flags);
VkPipelineTessellationStateCreateInfo PipelineTessellationStateCreateInfo(
uint32_t patchControlPoints);
VkGraphicsPipelineCreateInfo PipelineCreateInfo(
VkPipelineLayout layout,
VkRenderPass renderPass,
VkPipelineCreateFlags flags);
VkComputePipelineCreateInfo ComputePipelineCreateInfo(
VkPipelineLayout layout,
VkPipelineCreateFlags flags);
VkPushConstantRange PushConstantRange(
VkShaderStageFlags stageFlags,
uint32_t size,
uint32_t offset);
VkPipelineShaderStageCreateInfo PipelineShaderStageCreateInfo(
VkShaderStageFlagBits stage,
VkShaderModule module,
const char *entryName);
} // namespace init
} // namespace Vulkan
} // namespace Seele
+1 -1
View File
@@ -1,5 +1,5 @@
#include "Pipeline.h"
#include "DescriptorSets.h"
#include "Descriptor.h"
#include "Graphics.h"
using namespace Seele;
+1 -1
View File
@@ -1,6 +1,6 @@
#pragma once
#include "Enums.h"
#include "Graphics/Resources.h"
#include "Graphics/Pipeline.h"
namespace Seele
{
+149 -149
View File
@@ -1,9 +1,8 @@
#include "PipelineCache.h"
#include "Graphics.h"
#include "Enums.h"
#include "Initializer.h"
#include "RenderPass.h"
#include "DescriptorSets.h"
#include "Descriptor.h"
#include "Shader.h"
#include <fstream>
@@ -15,11 +14,12 @@ PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePat
, cacheFile(cacheFilePath)
{
std::ifstream stream(cacheFilePath, std::ios::binary | std::ios::ate);
VkPipelineCacheCreateInfo cacheCreateInfo;
cacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
cacheCreateInfo.pNext = nullptr;
cacheCreateInfo.flags = 0;
cacheCreateInfo.initialDataSize = 0;
VkPipelineCacheCreateInfo cacheCreateInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.initialDataSize = 0,
};
if(stream.good())
{
Array<uint8> cacheData;
@@ -52,41 +52,11 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf
{
PPipelineLayout layout = Gfx::PPipelineLayout(gfxInfo.pipelineLayout).cast<PipelineLayout>();
uint32 hash = layout->getHash();
VkPipelineVertexInputStateCreateInfo vertexInput =
init::PipelineVertexInputStateCreateInfo();
Array<VkVertexInputBindingDescription> bindings;
Array<VkVertexInputAttributeDescription> attributes;
if (gfxInfo.vertexDeclaration != nullptr)
{
PVertexDeclaration decl = gfxInfo.vertexDeclaration.cast<VertexDeclaration>();
for (const auto& elem : decl->elementList)
{
attributes.add(VkVertexInputAttributeDescription{
.location = elem.attributeIndex,
.binding = elem.binding,
.format = cast(elem.vertexFormat),
.offset = elem.offset,
});
auto res = bindings.find([elem](const VkVertexInputBindingDescription& b) {return b.binding == elem.binding; });
if (res == bindings.end())
{
bindings.add({});
res = bindings.end();
}
*res = VkVertexInputBindingDescription{
.binding = elem.binding,
.stride = elem.stride,
.inputRate = elem.instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX,
};
}
vertexInput.pVertexAttributeDescriptions = attributes.data();
vertexInput.vertexAttributeDescriptionCount = attributes.size();
vertexInput.pVertexBindingDescriptions = bindings.data();
vertexInput.vertexBindingDescriptionCount = bindings.size();
}
hash = CRC::Calculate(bindings.data(), bindings.size() * sizeof(VkVertexInputBindingDescription), CRC::CRC_32(), hash);
hash = CRC::Calculate(attributes.data(), attributes.size() * sizeof(VkVertexInputAttributeDescription), CRC::CRC_32(), hash);
VkPipelineVertexInputStateCreateInfo vertexInput = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
};
uint32 stageCount = 0;
VkPipelineShaderStageCreateInfo stageInfos[2];
@@ -112,52 +82,64 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf
};
}
hash = CRC::Calculate(stageInfos, sizeof(stageInfos), CRC::CRC_32(), hash);
VkPipelineInputAssemblyStateCreateInfo assemblyInfo =
init::PipelineInputAssemblyStateCreateInfo(
cast(gfxInfo.topology),
0,
false
);
VkPipelineInputAssemblyStateCreateInfo assemblyInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.topology = cast(gfxInfo.topology),
.primitiveRestartEnable = false,
};
hash = CRC::Calculate(&assemblyInfo, sizeof(assemblyInfo), CRC::CRC_32(), hash);
VkPipelineViewportStateCreateInfo viewportInfo =
init::PipelineViewportStateCreateInfo(
1,
1,
0
);
VkPipelineViewportStateCreateInfo viewportInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.viewportCount = 1,
.scissorCount = 1,
};
hash = CRC::Calculate(&viewportInfo, sizeof(viewportInfo), CRC::CRC_32(), hash);
VkPipelineRasterizationStateCreateInfo rasterizationState =
init::PipelineRasterizationStateCreateInfo(
cast(gfxInfo.rasterizationState.polygonMode),
gfxInfo.rasterizationState.cullMode,
(VkFrontFace)gfxInfo.rasterizationState.frontFace,
0
);
rasterizationState.depthBiasEnable = gfxInfo.rasterizationState.depthBiasEnable;
rasterizationState.depthBiasClamp = gfxInfo.rasterizationState.depthBiasClamp;
rasterizationState.depthBiasConstantFactor = gfxInfo.rasterizationState.depthBiasConstantFactor;
rasterizationState.depthBiasSlopeFactor = gfxInfo.rasterizationState.depthBiasSlopeFactor;
rasterizationState.depthClampEnable = gfxInfo.rasterizationState.depthClampEnable;
rasterizationState.lineWidth = gfxInfo.rasterizationState.lineWidth;
rasterizationState.rasterizerDiscardEnable = gfxInfo.rasterizationState.rasterizerDiscardEnable;
VkPipelineRasterizationStateCreateInfo rasterizationState = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.depthClampEnable = gfxInfo.rasterizationState.depthClampEnable,
.rasterizerDiscardEnable = gfxInfo.rasterizationState.rasterizerDiscardEnable,
.polygonMode = cast(gfxInfo.rasterizationState.polygonMode),
.cullMode = gfxInfo.rasterizationState.cullMode,
.frontFace = (VkFrontFace)gfxInfo.rasterizationState.frontFace,
.depthBiasEnable = gfxInfo.rasterizationState.depthBiasEnable,
.depthBiasConstantFactor = gfxInfo.rasterizationState.depthBiasConstantFactor,
.depthBiasClamp = gfxInfo.rasterizationState.depthBiasClamp,
.depthBiasSlopeFactor = gfxInfo.rasterizationState.depthBiasSlopeFactor,
.lineWidth = 0,
};
hash = CRC::Calculate(&rasterizationState, sizeof(rasterizationState), CRC::CRC_32(), hash);
VkPipelineMultisampleStateCreateInfo multisampleState =
init::PipelineMultisampleStateCreateInfo(
(VkSampleCountFlagBits)gfxInfo.multisampleState.samples,
0);
multisampleState.alphaToCoverageEnable = gfxInfo.multisampleState.alphaCoverageEnable;
multisampleState.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable;
multisampleState.minSampleShading = gfxInfo.multisampleState.minSampleShading;
multisampleState.sampleShadingEnable = gfxInfo.multisampleState.sampleShadingEnable;
VkPipelineMultisampleStateCreateInfo multisampleState = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.rasterizationSamples = (VkSampleCountFlagBits)gfxInfo.multisampleState.samples,
.sampleShadingEnable = gfxInfo.multisampleState.sampleShadingEnable,
.minSampleShading = gfxInfo.multisampleState.minSampleShading,
.alphaToCoverageEnable = gfxInfo.multisampleState.alphaCoverageEnable,
.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable,
};
hash = CRC::Calculate(&multisampleState, sizeof(multisampleState), CRC::CRC_32(), hash);
VkPipelineDepthStencilStateCreateInfo depthStencilState =
init::PipelineDepthStencilStateCreateInfo(
gfxInfo.depthStencilState.depthTestEnable,
gfxInfo.depthStencilState.depthWriteEnable,
cast(gfxInfo.depthStencilState.depthCompareOp)
);
VkPipelineDepthStencilStateCreateInfo depthStencilState = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.depthTestEnable = gfxInfo.depthStencilState.depthTestEnable,
.depthWriteEnable = gfxInfo.depthStencilState.depthWriteEnable,
.depthCompareOp = cast(gfxInfo.depthStencilState.depthCompareOp),
.depthBoundsTestEnable = gfxInfo.depthStencilState.depthBoundsTestEnable,
.front = (VkStencilOp)gfxInfo.depthStencilState.front,
.back = (VkStencilOp)gfxInfo.depthStencilState.back,
.minDepthBounds = gfxInfo.depthStencilState.minDepthBounds,
.maxDepthBounds = gfxInfo.depthStencilState.maxDepthBounds,
};
hash = CRC::Calculate(&depthStencilState, sizeof(depthStencilState), CRC::CRC_32(), hash);
const auto& colorAttachments = gfxInfo.renderPass->getLayout()->colorAttachments;
@@ -178,14 +160,16 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf
}
hash = CRC::Calculate(blendAttachments.data(), blendAttachments.size() * sizeof(VkPipelineColorBlendAttachmentState), CRC::CRC_32(), hash);
VkPipelineColorBlendStateCreateInfo blendState =
init::PipelineColorBlendStateCreateInfo(
(uint32)blendAttachments.size(),
blendAttachments.data()
);
blendState.logicOpEnable = gfxInfo.colorBlend.logicOpEnable;
blendState.logicOp = (VkLogicOp)gfxInfo.colorBlend.logicOp;
std::memcpy(blendState.blendConstants, gfxInfo.colorBlend.blendConstants, sizeof(gfxInfo.colorBlend.blendConstants));
VkPipelineColorBlendStateCreateInfo blendState = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.logicOpEnable = gfxInfo.colorBlend.logicOpEnable,
.logicOp = (VkLogicOp)gfxInfo.colorBlend.logicOp,
.attachmentCount = (uint32)blendAttachments.size(),
.pAttachments = blendAttachments.data(),
};
std::memcpy(blendState.blendConstants, gfxInfo.colorBlend.blendConstants.data(), sizeof(blendState.blendConstants));
uint32 numDynamicEnabled = 0;
StaticArray<VkDynamicState, 2> dynamicEnabled;
@@ -193,12 +177,12 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_SCISSOR;
hash = CRC::Calculate(dynamicEnabled.data(), dynamicEnabled.size() * sizeof(VkDynamicState), CRC::CRC_32(), hash);
VkPipelineDynamicStateCreateInfo dynamicState =
init::PipelineDynamicStateCreateInfo(
dynamicEnabled.data(),
numDynamicEnabled,
0
);
VkPipelineDynamicStateCreateInfo dynamicState = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
.pNext = nullptr,
.dynamicStateCount = (uint32)dynamicEnabled.size(),
.pDynamicStates = dynamicEnabled.data(),
};
if (graphicsPipelines.contains(hash))
{
@@ -278,46 +262,56 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
}
hash = CRC::Calculate(stageInfos, sizeof(stageInfos), CRC::CRC_32(), hash);
VkPipelineViewportStateCreateInfo viewportInfo =
init::PipelineViewportStateCreateInfo(
1,
1,
0
);
VkPipelineViewportStateCreateInfo viewportInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.viewportCount = 1,
.scissorCount = 1,
};
hash = CRC::Calculate(&viewportInfo, sizeof(viewportInfo), CRC::CRC_32(), hash);
VkPipelineRasterizationStateCreateInfo rasterizationState =
init::PipelineRasterizationStateCreateInfo(
cast(gfxInfo.rasterizationState.polygonMode),
gfxInfo.rasterizationState.cullMode,
(VkFrontFace)gfxInfo.rasterizationState.frontFace,
0
);
rasterizationState.depthBiasEnable = gfxInfo.rasterizationState.depthBiasEnable;
rasterizationState.depthBiasClamp = gfxInfo.rasterizationState.depthBiasClamp;
rasterizationState.depthBiasConstantFactor = gfxInfo.rasterizationState.depthBiasConstantFactor;
rasterizationState.depthBiasSlopeFactor = gfxInfo.rasterizationState.depthBiasSlopeFactor;
rasterizationState.depthClampEnable = gfxInfo.rasterizationState.depthClampEnable;
rasterizationState.lineWidth = gfxInfo.rasterizationState.lineWidth;
rasterizationState.rasterizerDiscardEnable = gfxInfo.rasterizationState.rasterizerDiscardEnable;
VkPipelineRasterizationStateCreateInfo rasterizationState = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.depthClampEnable = gfxInfo.rasterizationState.depthClampEnable,
.rasterizerDiscardEnable = gfxInfo.rasterizationState.rasterizerDiscardEnable,
.polygonMode = cast(gfxInfo.rasterizationState.polygonMode),
.cullMode = gfxInfo.rasterizationState.cullMode,
.frontFace = (VkFrontFace)gfxInfo.rasterizationState.frontFace,
.depthBiasEnable = gfxInfo.rasterizationState.depthBiasEnable,
.depthBiasConstantFactor = gfxInfo.rasterizationState.depthBiasConstantFactor,
.depthBiasClamp = gfxInfo.rasterizationState.depthBiasClamp,
.depthBiasSlopeFactor = gfxInfo.rasterizationState.depthBiasSlopeFactor,
.lineWidth = 0,
};
hash = CRC::Calculate(&rasterizationState, sizeof(rasterizationState), CRC::CRC_32(), hash);
VkPipelineMultisampleStateCreateInfo multisampleState =
init::PipelineMultisampleStateCreateInfo(
(VkSampleCountFlagBits)gfxInfo.multisampleState.samples,
0);
multisampleState.alphaToCoverageEnable = gfxInfo.multisampleState.alphaCoverageEnable;
multisampleState.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable;
multisampleState.minSampleShading = gfxInfo.multisampleState.minSampleShading;
multisampleState.sampleShadingEnable = gfxInfo.multisampleState.sampleShadingEnable;
VkPipelineMultisampleStateCreateInfo multisampleState = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.rasterizationSamples = (VkSampleCountFlagBits)gfxInfo.multisampleState.samples,
.sampleShadingEnable = gfxInfo.multisampleState.sampleShadingEnable,
.minSampleShading = gfxInfo.multisampleState.minSampleShading,
.alphaToCoverageEnable = gfxInfo.multisampleState.alphaCoverageEnable,
.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable,
};
hash = CRC::Calculate(&multisampleState, sizeof(multisampleState), CRC::CRC_32(), hash);
VkPipelineDepthStencilStateCreateInfo depthStencilState =
init::PipelineDepthStencilStateCreateInfo(
gfxInfo.depthStencilState.depthTestEnable,
gfxInfo.depthStencilState.depthWriteEnable,
cast(gfxInfo.depthStencilState.depthCompareOp)
);
VkPipelineDepthStencilStateCreateInfo depthStencilState = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.depthTestEnable = gfxInfo.depthStencilState.depthTestEnable,
.depthWriteEnable = gfxInfo.depthStencilState.depthWriteEnable,
.depthCompareOp = cast(gfxInfo.depthStencilState.depthCompareOp),
.depthBoundsTestEnable = gfxInfo.depthStencilState.depthBoundsTestEnable,
.front = (VkStencilOp)gfxInfo.depthStencilState.front,
.back = (VkStencilOp)gfxInfo.depthStencilState.back,
.minDepthBounds = gfxInfo.depthStencilState.minDepthBounds,
.maxDepthBounds = gfxInfo.depthStencilState.maxDepthBounds,
};
hash = CRC::Calculate(&depthStencilState, sizeof(depthStencilState), CRC::CRC_32(), hash);
const auto& colorAttachments = gfxInfo.renderPass->getLayout()->colorAttachments;
@@ -338,14 +332,16 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
}
hash = CRC::Calculate(blendAttachments.data(), blendAttachments.size() * sizeof(VkPipelineColorBlendAttachmentState), CRC::CRC_32(), hash);
VkPipelineColorBlendStateCreateInfo blendState =
init::PipelineColorBlendStateCreateInfo(
(uint32)blendAttachments.size(),
blendAttachments.data()
);
blendState.logicOpEnable = gfxInfo.colorBlend.logicOpEnable;
blendState.logicOp = (VkLogicOp)gfxInfo.colorBlend.logicOp;
std::memcpy(blendState.blendConstants, gfxInfo.colorBlend.blendConstants, sizeof(gfxInfo.colorBlend.blendConstants));
VkPipelineColorBlendStateCreateInfo blendState = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.logicOpEnable = gfxInfo.colorBlend.logicOpEnable,
.logicOp = (VkLogicOp)gfxInfo.colorBlend.logicOp,
.attachmentCount = (uint32)blendAttachments.size(),
.pAttachments = blendAttachments.data(),
};
std::memcpy(blendState.blendConstants, gfxInfo.colorBlend.blendConstants.data(), sizeof(blendState.blendConstants));
uint32 numDynamicEnabled = 0;
StaticArray<VkDynamicState, 2> dynamicEnabled;
@@ -353,12 +349,12 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_SCISSOR;
hash = CRC::Calculate(dynamicEnabled.data(), dynamicEnabled.size() * sizeof(VkDynamicState), CRC::CRC_32(), hash);
VkPipelineDynamicStateCreateInfo dynamicState =
init::PipelineDynamicStateCreateInfo(
dynamicEnabled.data(),
numDynamicEnabled,
0
);
VkPipelineDynamicStateCreateInfo dynamicState = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
.pNext = nullptr,
.dynamicStateCount = (uint32)dynamicEnabled.size(),
.pDynamicStates = dynamicEnabled.data(),
};
if (graphicsPipelines.contains(hash))
{
@@ -409,10 +405,14 @@ PComputePipeline PipelineCache::createPipeline(Gfx::ComputePipelineCreateInfo co
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
.pNext = 0,
.flags = 0,
.stage = init::PipelineShaderStageCreateInfo(
VK_SHADER_STAGE_COMPUTE_BIT,
computeStage->getModuleHandle(),
computeStage->getEntryPointName()),
.stage = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
.module = computeStage->getModuleHandle(),
.pName = computeStage->getEntryPointName(),
},
.layout = layout->getHandle(),
.basePipelineHandle = VK_NULL_HANDLE,
.basePipelineIndex = 0,
+25 -25
View File
@@ -1,8 +1,7 @@
#include "Queue.h"
#include "Initializer.h"
#include "Graphics.h"
#include "Allocator.h"
#include "CommandBuffer.h"
#include "Command.h"
using namespace Seele;
using namespace Seele::Vulkan;
@@ -19,45 +18,46 @@ Queue::~Queue()
{
}
void Queue::submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores, VkSemaphore *signalSemaphores)
void Queue::submitCommandBuffer(PCommand command, uint32 numSignalSemaphores, VkSemaphore *signalSemaphores)
{
std::scoped_lock lck(queueLock);
assert(cmdBuffer->state == Command::State::End);
std::unique_lock lock(queueLock);
assert(command->state == Command::State::End);
PFence fence = cmdBuffer->fence;
PFence fence = command->fence;
assert(!fence->isSignaled());
const VkCommandBuffer cmdBuffers[] = {cmdBuffer->handle};
VkSubmitInfo submitInfo =
init::SubmitInfo();
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = cmdBuffers;
submitInfo.signalSemaphoreCount = static_cast<uint32>(numSignalSemaphores);
submitInfo.pSignalSemaphores = signalSemaphores;
VkCommandBuffer cmdHandle = command->handle;
Array<VkSemaphore> waitSemaphores;
if (cmdBuffer->waitSemaphores.size() > 0)
if (command->waitSemaphores.size() > 0)
{
for (PSemaphore semaphore : cmdBuffer->waitSemaphores)
for (PSemaphore semaphore : command->waitSemaphores)
{
waitSemaphores.add(semaphore->getHandle());
}
submitInfo.waitSemaphoreCount = static_cast<uint32>(cmdBuffer->waitSemaphores.size());
submitInfo.pWaitSemaphores = waitSemaphores.data();
submitInfo.pWaitDstStageMask = cmdBuffer->waitFlags.data();
}
VkSubmitInfo submitInfo = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.pNext = nullptr,
.waitSemaphoreCount = static_cast<uint32>(command->waitSemaphores.size()),
.pWaitSemaphores = waitSemaphores.data(),
.pWaitDstStageMask = command->waitFlags.data(),
.commandBufferCount = 1,
.pCommandBuffers = &cmdHandle,
.signalSemaphoreCount = static_cast<uint32>(numSignalSemaphores),
.pSignalSemaphores = signalSemaphores,
};
VK_CHECK(vkQueueSubmit(queue, 1, &submitInfo, fence->getHandle()));
cmdBuffer->state = Command::State::Submit;
cmdBuffer->waitFlags.clear();
cmdBuffer->waitSemaphores.clear();
command->state = Command::State::Submit;
command->waitFlags.clear();
command->waitSemaphores.clear();
if (Gfx::waitIdleOnSubmit)
{
fence->wait(200 * 1000ull);
}
cmdBuffer->checkFence();
graphics->getStagingManager()->clearPending();
command->checkFence();
}
+5 -5
View File
@@ -12,16 +12,16 @@ class Queue
public:
Queue(PGraphics graphics, Gfx::QueueType queueType, uint32 familyIndex, uint32 queueIndex);
virtual ~Queue();
void submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores = 0, VkSemaphore *signalSemaphore = nullptr);
inline void submitCommandBuffer(PCmdBuffer cmdBuffer, VkSemaphore signalSemaphore)
void submitCommandBuffer(PCommand command, uint32 numSignalSemaphores = 0, VkSemaphore *signalSemaphore = nullptr);
void submitCommandBuffer(PCommand command, VkSemaphore signalSemaphore)
{
submitCommandBuffer(cmdBuffer, 1, &signalSemaphore);
submitCommandBuffer(command, 1, &signalSemaphore);
}
uint32 getFamilyIndex() const
constexpr uint32 getFamilyIndex() const
{
return familyIndex;
}
inline VkQueue getHandle() const
constexpr VkQueue getHandle() const
{
return queue;
}
+79 -78
View File
@@ -1,5 +1,4 @@
#include "RenderPass.h"
#include "Initializer.h"
#include "Graphics.h"
#include "Framebuffer.h"
#include "Texture.h"
@@ -25,107 +24,104 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::ORenderTargetLayout _layout, Gfx
for (auto& inputAttachment : layout->inputAttachments)
{
PTexture2D image = inputAttachment->getTexture().cast<Texture2D>();
VkAttachmentDescription& desc = attachments.add();
desc.flags = 0;
desc.format = cast(image->getFormat());
desc.storeOp = cast(inputAttachment->getStoreOp());
desc.loadOp = cast(inputAttachment->getLoadOp());
desc.stencilStoreOp = cast(inputAttachment->getStencilStoreOp());
desc.stencilLoadOp = cast(inputAttachment->getStencilLoadOp());
desc.initialLayout = image->isDepthStencil() ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
desc.finalLayout = desc.initialLayout;
VkAttachmentDescription& desc = attachments.add() = {
.flags = 0,
.format = cast(image->getFormat()),
.loadOp = cast(inputAttachment->getLoadOp()),
.storeOp = cast(inputAttachment->getStoreOp()),
.stencilLoadOp = cast(inputAttachment->getStencilLoadOp()),
.stencilStoreOp = cast(inputAttachment->getStencilStoreOp()),
.initialLayout = image->isDepthStencil() ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.finalLayout = desc.initialLayout,
};
VkAttachmentReference &ref = inputRefs.add();
ref.layout = desc.initialLayout;
ref.attachment = attachmentCounter;
attachmentCounter++;
inputRefs.add() = {
.attachment = attachmentCounter++,
.layout = desc.initialLayout,
};
}
for (auto& colorAttachment : layout->colorAttachments)
{
VkAttachmentDescription& desc = attachments.add();
desc.flags = 0;
desc.samples = (VkSampleCountFlagBits)colorAttachment->getNumSamples();
desc.format = cast(colorAttachment->getFormat());
desc.storeOp = cast(colorAttachment->getStoreOp());
desc.loadOp = cast(colorAttachment->getLoadOp());
desc.stencilStoreOp = cast(colorAttachment->getStencilStoreOp());
desc.stencilLoadOp = cast(colorAttachment->getStencilLoadOp());
desc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachments.add() = {
.flags = 0,
.format = cast(colorAttachment->getFormat()),
.samples = (VkSampleCountFlagBits)colorAttachment->getNumSamples(),
.loadOp = cast(colorAttachment->getLoadOp()),
.storeOp = cast(colorAttachment->getStoreOp()),
.stencilLoadOp = cast(colorAttachment->getStencilLoadOp()),
.stencilStoreOp = cast(colorAttachment->getStencilStoreOp()),
.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
};
VkClearValue& clearValue = clearValues.add();
if(desc.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
if(attachments.back().loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
{
clearValue = cast(colorAttachment->clear);
}
VkAttachmentReference &ref = colorRefs.add();
ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
ref.attachment = attachmentCounter;
attachmentCounter++;
colorRefs.add() = {
.attachment = attachmentCounter++,
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
};
}
if (layout->depthAttachment != nullptr)
{
PTexture2D image = layout->depthAttachment->getTexture().cast<Texture2D>();
VkAttachmentDescription& desc = attachments.add();
desc.flags = 0;
desc.samples = (VkSampleCountFlagBits)image->getNumSamples();
desc.format = cast(image->getFormat());
desc.storeOp = cast(layout->depthAttachment->getStoreOp());
desc.loadOp = cast(layout->depthAttachment->getLoadOp());
desc.stencilStoreOp = cast(layout->depthAttachment->getStencilStoreOp());
desc.stencilLoadOp = cast(layout->depthAttachment->getStencilLoadOp());
desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
attachments.add() = {
.flags = 0,
.format = cast(image->getFormat()),
.samples = (VkSampleCountFlagBits)image->getNumSamples(),
.loadOp = cast(layout->depthAttachment->getLoadOp()),
.storeOp = cast(layout->depthAttachment->getStoreOp()),
.stencilLoadOp = cast(layout->depthAttachment->getStencilLoadOp()),
.stencilStoreOp = cast(layout->depthAttachment->getStencilStoreOp()),
.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
};
VkClearValue& clearValue = clearValues.add();
if(desc.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
if(attachments.back().loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
{
clearValue = cast(layout->depthAttachment->clear);
}
VkAttachmentReference &ref = depthRef;
ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
ref.attachment = attachmentCounter;
attachmentCounter++;
depthRef = {
.attachment = attachmentCounter++,
.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
};
}
VkSubpassDescription subPassDesc =
init::SubpassDescription(
VK_PIPELINE_BIND_POINT_GRAPHICS,
(uint32)colorRefs.size(),
colorRefs.data(),
&depthRef,
(uint32)inputRefs.size(),
inputRefs.data());
VkSubpassDependency dependency = {};
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0;
VkSubpassDescription subPassDesc = {
.flags = 0,
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
.inputAttachmentCount = (uint32)inputRefs.size(),
.pInputAttachments = inputRefs.data(),
.colorAttachmentCount = (uint32)colorRefs.size(),
.pColorAttachments = colorRefs.data(),
.pDepthStencilAttachment = &depthRef,
};
VkSubpassDependency dependency = {
.srcSubpass = VK_SUBPASS_EXTERNAL,
.dstSubpass = 0,
.srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
};
dependency.srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
dependency.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
VkRenderPassCreateInfo info =
init::RenderPassCreateInfo(
(uint32)attachments.size(),
attachments.data(),
1,
&subPassDesc,
1,
&dependency);
VkRenderPassCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
.pNext = nullptr,
.attachmentCount = (uint32)attachments.size(),
.pAttachments = attachments.data(),
.subpassCount = 1,
.pSubpasses = &subPassDesc,
.dependencyCount = 1,
.pDependencies = &dependency,
};
VK_CHECK(vkCreateRenderPass(graphics->getDevice(), &info, nullptr, &renderPass));
}
RenderPass::~RenderPass()
{
vkDestroyRenderPass(graphics->getDevice(), renderPass, nullptr);
}
uint32 RenderPass::getFramebufferHash()
{
FramebufferDescription description;
std::memset(&description, 0, sizeof(FramebufferDescription));
for (auto& inputAttachment : layout->inputAttachments)
@@ -143,6 +139,11 @@ uint32 RenderPass::getFramebufferHash()
PTexture2D tex = layout->depthAttachment->getTexture().cast<Texture2D>();
description.depthAttachment = tex->getView();
}
return CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32());
framebufferHash = CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32());
}
RenderPass::~RenderPass()
{
vkDestroyRenderPass(graphics->getDevice(), renderPass, nullptr);
}
+10 -6
View File
@@ -11,28 +11,32 @@ class RenderPass : public Gfx::RenderPass
public:
RenderPass(PGraphics graphics, Gfx::ORenderTargetLayout layout, Gfx::PViewport viewport);
virtual ~RenderPass();
uint32 getFramebufferHash();
inline VkRenderPass getHandle() const
constexpr uint32 getFramebufferHash() const
{
return framebufferHash;
}
constexpr VkRenderPass getHandle() const
{
return renderPass;
}
inline size_t getClearValueCount() const
constexpr size_t getClearValueCount() const
{
return clearValues.size();
}
inline VkClearValue *getClearValues() const
constexpr VkClearValue *getClearValues() const
{
return clearValues.data();
}
inline VkRect2D getRenderArea() const
constexpr VkRect2D getRenderArea() const
{
return renderArea;
}
inline VkSubpassContents getSubpassContents() const
constexpr VkSubpassContents getSubpassContents() const
{
return subpassContents;
}
private:
uint32 framebufferHash;
PGraphics graphics;
VkRenderPass renderPass;
Array<VkClearValue> clearValues;
+44 -30
View File
@@ -1,9 +1,8 @@
#include "RenderTarget.h"
#include "Resources.h"
#include "Graphics.h"
#include "Initializer.h"
#include "Enums.h"
#include "CommandBuffer.h"
#include "Command.h"
#include <GLFW/glfw3.h>
using namespace Seele;
@@ -184,11 +183,13 @@ void Window::advanceBackBuffer()
backBufferImages[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkClearColorValue clearColor = {0.0f, 0.0f, 0.0f, 0.0f};
PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands();
VkImageSubresourceRange range = init::ImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT);
PCommand command = graphics->getGraphicsCommands()->getCommands();
VkImageSubresourceRange range = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
};
vkCmdClearColorImage(
cmdBuffer->getHandle(),
backBufferImages[currentImageIndex]->getHandle(),
command->getHandle(),
backBufferHandles[currentImageIndex],
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
&clearColor,
1,
@@ -264,23 +265,26 @@ void Window::createSwapchain()
throw new std::logic_error("Trying to buffer more than the maximum number of frames");
}
VkExtent2D extent = {
.width = getWidth(),
.height = getHeight(),
VkSwapchainCreateInfoKHR swapchainInfo = {
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
.pNext = nullptr,
.flags = 0,
.surface = surface,
.minImageCount = desiredNumBuffers,
.imageFormat = surfaceFormat.format,
.imageColorSpace = surfaceFormat.colorSpace,
.imageExtent = {
.width = getWidth(),
.height = getHeight(),
},
.imageArrayLayers = 1,
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
.presentMode = presentMode,
.clipped = VK_TRUE,
};
VkSwapchainCreateInfoKHR swapchainInfo =
init::SwapchainCreateInfo(
surface,
desiredNumBuffers,
surfaceFormat.format,
surfaceFormat.colorSpace,
extent,
1,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
presentMode,
VK_TRUE);
VK_CHECK(vkCreateSwapchainKHR(graphics->getDevice(), &swapchainInfo, nullptr, &swapchain));
uint32 numSwapchainImages;
@@ -289,24 +293,34 @@ void Window::createSwapchain()
VK_CHECK(vkGetSwapchainImagesKHR(graphics->getDevice(), swapchain, &numSwapchainImages, swapchainImages.data()));
TextureCreateInfo backBufferCreateInfo;
backBufferCreateInfo.width = getWidth();
backBufferCreateInfo.height = getHeight();
backBufferCreateInfo.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
backBufferCreateInfo.sourceData.owner = Gfx::QueueType::GRAPHICS;
backBufferCreateInfo.format = cast(surfaceFormat.format);
TextureCreateInfo backBufferCreateInfo = {
.sourceData = {
.owner = Gfx::QueueType::GRAPHICS,
},
.format = cast(surfaceFormat.format),
.width = getWidth(),
.height = getHeight(),
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
};
for (uint32 i = 0; i < numSwapchainImages; ++i)
{
imageAcquired[i] = new Semaphore(graphics);
renderFinished[i] = new Semaphore(graphics);
backBufferImages[i] = new Texture2D(graphics, backBufferCreateInfo, swapchainImages[i]);
backBufferHandles[i] = swapchainImages[i];
VkClearColorValue clearColor;
std::memset(&clearColor, 0, sizeof(VkClearColorValue));
backBufferImages[i]->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkImageSubresourceRange range = init::ImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT);
VkImageSubresourceRange range = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
};
PCommand command = graphics->getGraphicsCommands()->getCommands();
vkCmdClearColorImage(command->getHandle(), backBufferImages[i]->getHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
vkCmdClearColorImage(command->getHandle(), backBufferHandles[i], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
backBufferImages[i]->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
}
graphics->getGraphicsCommands()->submitCommands();
@@ -45,6 +45,7 @@ protected:
void choosePresentMode(const Array<VkPresentModeKHR> &modes);
OTexture2D backBufferImages[Gfx::numFramesBuffered];
VkImage backBufferHandles[Gfx::numFramesBuffered];
OSemaphore renderFinished[Gfx::numFramesBuffered];
OSemaphore imageAcquired[Gfx::numFramesBuffered];
PSemaphore imageAcquiredSemaphore;
+23 -14
View File
@@ -1,6 +1,5 @@
#include "Resources.h"
#include "Enums.h"
#include "Initializer.h"
#include "Graphics.h"
using namespace Seele;
@@ -79,14 +78,18 @@ void Fence::reset()
void Fence::wait(uint32 timeout)
{
VkFence fences[] = {fence};
VkResult res = vkWaitForFences(graphics->getDevice(), 1, fences, true, timeout);
if (res == VK_SUCCESS)
VkResult r = vkWaitForFences(graphics->getDevice(), 1, fences, true, timeout);
if (r == VK_SUCCESS)
{
signaled = true;
}
if (res != VK_NOT_READY)
else if (r == VK_TIMEOUT)
{
VK_CHECK(res);
return;
}
else if (r != VK_NOT_READY)
{
VK_CHECK(r);
}
}
@@ -119,26 +122,32 @@ void DestructionManager::queueSemaphore(PCommand cmd, VkSemaphore sem)
sems[cmd].add(sem);
}
void DestructionManager::notifyCmdComplete(PCommand cmdbuffer)
void DestructionManager::queueAllocation(PCommand cmd, OSubAllocation alloc)
{
for(auto buf : buffers[cmdbuffer])
allocs[cmd].add(std::move(alloc));
}
void DestructionManager::notifyCmdComplete(PCommand cmd)
{
for(auto buf : buffers[cmd])
{
vkDestroyBuffer(graphics->getDevice(), buf, nullptr);
}
for(auto view : views[cmdbuffer])
for(auto view : views[cmd])
{
vkDestroyImageView(graphics->getDevice(), view, nullptr);
}
for(auto img : images[cmdbuffer])
for(auto img : images[cmd])
{
vkDestroyImage(graphics->getDevice(), img, nullptr);
}
for (auto sem : sems[cmdbuffer])
for (auto sem : sems[cmd])
{
vkDestroySemaphore(graphics->getDevice(), sem, nullptr);
}
buffers[cmdbuffer].clear();
images[cmdbuffer].clear();
views[cmdbuffer].clear();
sems[cmdbuffer].clear();
buffers[cmd].clear();
images[cmd].clear();
views[cmd].clear();
sems[cmd].clear();
allocs[cmd].clear();
}
+3 -1
View File
@@ -8,7 +8,7 @@ namespace Seele
{
namespace Vulkan
{
DECLARE_REF(DescriptorAllocator)
DECLARE_REF(DescriptorPool)
DECLARE_REF(CommandPool)
DECLARE_REF(Command)
DECLARE_REF(Graphics)
@@ -61,6 +61,7 @@ public:
void queueImage(PCommand cmd, VkImage image);
void queueImageView(PCommand cmd, VkImageView view);
void queueSemaphore(PCommand cmd, VkSemaphore sem);
void queueAllocation(PCommand cmd, OSubAllocation alloc);
void notifyCmdComplete(PCommand cmdbuffer);
private:
PGraphics graphics;
@@ -68,6 +69,7 @@ private:
Map<PCommand, List<VkImage>> images;
Map<PCommand, List<VkImageView>> views;
Map<PCommand, List<VkSemaphore>> sems;
Map<PCommand, List<OSubAllocation>> allocs;
};
DEFINE_REF(DestructionManager)
+179 -159
View File
@@ -1,6 +1,5 @@
#include "Texture.h"
#include "Initializer.h"
#include "CommandBuffer.h"
#include "Command.h"
#include <math.h>
using namespace Seele;
@@ -26,15 +25,15 @@ VkImageAspectFlags getAspectFromFormat(Gfx::SeFormat format)
}
}
TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType,
const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage)
: currentOwner(owner)
, graphics(graphics)
, sizeX(createInfo.width)
, sizeY(createInfo.height)
, sizeZ(createInfo.depth)
, arrayCount(createInfo.bArray ? createInfo.arrayLayers : 1)
, layerCount(1)
, width(createInfo.width)
, height(createInfo.height)
, depth(createInfo.depth)
, arrayCount(createInfo.elements)
, layerCount(createInfo.layers)
, mipLevels(createInfo.mipLevels)
, samples(createInfo.samples)
, format(createInfo.format)
@@ -45,64 +44,73 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
{
if (existingImage == VK_NULL_HANDLE)
{
PAllocator allocator = graphics->getAllocator();
VkImageCreateInfo info =
init::ImageCreateInfo();
info.extent.width = sizeX;
info.extent.height = sizeY;
info.extent.depth = sizeZ;
info.format = cast(format);
PAllocator pool = graphics->getAllocator();
VkImageType type = VK_IMAGE_TYPE_MAX_ENUM;
VkImageCreateFlags flags = 0;
switch (viewType)
{
case VK_IMAGE_VIEW_TYPE_1D:
case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
info.imageType = VK_IMAGE_TYPE_1D;
type = VK_IMAGE_TYPE_1D;
break;
case VK_IMAGE_VIEW_TYPE_2D:
case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
info.imageType = VK_IMAGE_TYPE_2D;
type = VK_IMAGE_TYPE_2D;
break;
case VK_IMAGE_VIEW_TYPE_3D:
info.imageType = VK_IMAGE_TYPE_3D;
type = VK_IMAGE_TYPE_3D;
break;
case VK_IMAGE_VIEW_TYPE_CUBE:
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
info.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
info.imageType = VK_IMAGE_TYPE_2D;
type = VK_IMAGE_TYPE_2D;
flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
layerCount = 6 * arrayCount;
break;
default:
break;
}
VkImageCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.pNext = nullptr,
.flags = flags,
.imageType = type,
.format = cast(format),
.extent = {
.width = width,
.height = height,
.depth = depth,
},
.mipLevels = mipLevels,
.arrayLayers = arrayCount * layerCount,
.samples = (VkSampleCountFlagBits)samples,
.tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = usage
| VK_IMAGE_USAGE_TRANSFER_DST_BIT
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
| VK_IMAGE_USAGE_SAMPLED_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.initialLayout = cast(layout),
};
info.initialLayout = cast(layout);
info.mipLevels = mipLevels;
info.arrayLayers = arrayCount * layerCount;
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
info.samples = (VkSampleCountFlagBits)samples;
info.tiling = VK_IMAGE_TILING_OPTIMAL;
info.usage = usage;
// Most of these flags will almost always be used
info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
info.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
VK_CHECK(vkCreateImage(graphics->getDevice(), &info, nullptr, &image));
VkMemoryDedicatedRequirements memDedicatedRequirements;
memDedicatedRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
memDedicatedRequirements.pNext = nullptr;
VkImageMemoryRequirementsInfo2 reqInfo;
reqInfo.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2;
reqInfo.pNext = nullptr;
reqInfo.image = image;
VkMemoryRequirements2 requirements;
requirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
requirements.pNext = &memDedicatedRequirements;
VkMemoryDedicatedRequirements memDedicatedRequirements = {
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
.pNext = nullptr,
};
VkImageMemoryRequirementsInfo2 reqInfo = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
.pNext = nullptr,
.image = image,
};
VkMemoryRequirements2 requirements = {
.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
.pNext = &memDedicatedRequirements,
};
vkGetImageMemoryRequirements2(graphics->getDevice(), &reqInfo, &requirements);
allocation = allocator->allocate(requirements, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, image);
allocation = pool->allocate(requirements, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, image);
vkBindImageMemory(graphics->getDevice(), image, allocation->getHandle(), allocation->getOffset());
}
@@ -110,31 +118,39 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
if(sourceData.size > 0)
{
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
OStagingBuffer staging = graphics->getStagingManager()->create(sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
OStagingBuffer staging = graphics->getStagingManager()->create(sourceData.size);
void* data = staging->map();
std::memcpy(data, sourceData.data, sourceData.size);
staging->flush();
PCommandBufferManager cmdBufferManager = graphics->getQueueCommands(currentOwner);
VkBufferImageCopy region;
region.bufferOffset = 0;
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
PCommandPool commandPool = graphics->getQueueCommands(currentOwner);
VkBufferImageCopy region = {
.bufferOffset = 0,
.bufferRowLength = 0,
.bufferImageHeight = 0,
.imageSubresource = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = arrayCount * layerCount,
},
.imageOffset = {
.x = 0,
.y = 0,
.z = 0,
},
.imageExtent = {
.width = width,
.height = height,
.depth = depth
},
};
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = arrayCount * layerCount;
region.imageOffset = {0, 0, 0};
region.imageExtent = {sizeX, sizeY, sizeZ};
vkCmdCopyBufferToImage(cmdBufferManager->getCommands()->getHandle(),
vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(),
staging->getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
// When loading a texture from a file, we will almost always use it as a texture map for fragment shaders
changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
graphics->getStagingManager()->release(std::move(staging));
}
else if(usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
{
@@ -145,74 +161,62 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
}
VkImageViewCreateInfo viewInfo =
init::ImageViewCreateInfo();
viewInfo.subresourceRange = init::ImageSubresourceRange(aspect);
viewInfo.viewType = viewType;
viewInfo.image = image;
viewInfo.format = cast(format);
viewInfo.subresourceRange.layerCount = layerCount;
viewInfo.subresourceRange.levelCount = mipLevels;
VkImageViewCreateInfo viewInfo = {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.image = image,
.viewType = viewType,
.format = cast(format),
.subresourceRange = {
.aspectMask = aspect,
.levelCount = mipLevels,
.layerCount = layerCount,
},
};
VK_CHECK(vkCreateImageView(graphics->getDevice(), &viewInfo, nullptr, &defaultView));
}
TextureHandle::~TextureHandle()
TextureBase::~TextureBase()
{
graphics->getDestructionManager()->queueImage(graphics->getQueueCommands(currentOwner)->getCommands(), image);
graphics->getDestructionManager()->queueImageView(graphics->getQueueCommands(currentOwner)->getCommands(), defaultView);
}
TextureHandle* TextureBase::cast(Gfx::PTexture texture)
{
if(texture == nullptr)
{
return nullptr;
}
if(texture->getTexture2D() != nullptr)
{
PTexture2D texture2D = texture.cast<Texture2D>();
return texture2D->textureHandle;
}
if(texture->getTexture3D() != nullptr)
{
PTexture3D texture3D = texture.cast<Texture3D>();
return texture3D->textureHandle;
}
if(texture->getTextureCube() != nullptr)
{
PTextureCube textureCube = texture.cast<TextureCube>();
return textureCube->textureHandle;
}
return nullptr;
}
void TextureHandle::changeLayout(Gfx::SeImageLayout newLayout)
void TextureBase::changeLayout(Gfx::SeImageLayout newLayout)
{
VkImageMemoryBarrier barrier =
init::ImageMemoryBarrier(
image,
cast(layout),
cast(newLayout));
barrier.subresourceRange =
init::ImageSubresourceRange(aspect);
barrier.subresourceRange.layerCount = layerCount;
PCommandBufferManager cmdManager = graphics->getQueueCommands(currentOwner);
vkCmdPipelineBarrier(cmdManager->getCommands()->getHandle(),
VkImageMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
.oldLayout = cast(layout),
.newLayout = cast(newLayout),
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = image,
.subresourceRange = {
.aspectMask = aspect,
.levelCount = 1,
.layerCount = layerCount,
},
};
PCommandPool commandPool = graphics->getQueueCommands(currentOwner);
vkCmdPipelineBarrier(commandPool->getCommands()->getHandle(),
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
0, 0, nullptr, 0, nullptr, 1, &barrier);
cmdManager->submitCommands();
commandPool->submitCommands();
layout = newLayout;
}
void TextureHandle::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
void TextureBase::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
{
uint64 imageSize = sizeX * sizeY * sizeZ * Gfx::getFormatInfo(format).blockSize;
uint64 imageSize = width * height * depth * Gfx::getFormatInfo(format).blockSize;
OStagingBuffer stagingbuffer = graphics->getStagingManager()->create(imageSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true);
OStagingBuffer stagingbuffer = graphics->getStagingManager()->create(imageSize);
auto prevlayout = layout;
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
PCommand cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
//Gfx::FormatCompatibilityInfo formatInfo = Gfx::getFormatInfo(format);
VkBufferImageCopy region = {
.bufferOffset = 0,
@@ -224,32 +228,43 @@ void TextureHandle::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Ar
.baseArrayLayer = arrayLayer * layerCount + face,
.layerCount = 1,
},
.imageOffset = { 0, 0, 0 },
.imageExtent = { sizeX, sizeY, sizeZ },
.imageOffset = {
.x = 0,
.y = 0,
.z = 0,
},
.imageExtent = {
.width = width,
.height = height,
.depth = depth
},
};
vkCmdCopyImageToBuffer(cmdBuffer->getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingbuffer->getHandle(), 1, &region);
changeLayout(prevlayout);
buffer.resize(stagingbuffer->getSize());
void* data = stagingbuffer->map();
std::memcpy(buffer.data(), data, buffer.size());
graphics->getStagingManager()->release(std::move(stagingbuffer));
}
void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner)
void TextureBase::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
VkImageMemoryBarrier imageBarrier =
init::ImageMemoryBarrier();
imageBarrier.image = image;
imageBarrier.oldLayout = cast(layout);
imageBarrier.newLayout = cast(layout);
imageBarrier.subresourceRange = init::ImageSubresourceRange(aspect);
PCommandBufferManager sourceManager = graphics->getQueueCommands(currentOwner);
PCommandBufferManager dstManager = nullptr;
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
VkImageMemoryBarrier imageBarrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
.oldLayout = cast(layout),
.newLayout = cast(layout),
.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(currentOwner),
.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner),
.image = image,
.subresourceRange = {
.aspectMask = aspect,
},
};
PCommandPool sourcePool = graphics->getQueueCommands(currentOwner);
PCommandPool dstPool = nullptr;
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
imageBarrier.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(currentOwner);
imageBarrier.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner);
if (currentOwner == Gfx::QueueType::TRANSFER || currentOwner == Gfx::QueueType::DEDICATED_TRANSFER)
{
imageBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
@@ -269,56 +284,61 @@ void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
imageBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstManager = graphics->getTransferCommands();
dstPool = graphics->getTransferCommands();
}
else if (newOwner == Gfx::QueueType::DEDICATED_TRANSFER)
{
imageBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstManager = graphics->getDedicatedTransferCommands();
dstPool = graphics->getDedicatedTransferCommands();
}
else if (newOwner == Gfx::QueueType::COMPUTE)
{
imageBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
dstManager = graphics->getComputeCommands();
dstPool = graphics->getComputeCommands();
}
else if (newOwner == Gfx::QueueType::GRAPHICS)
{
imageBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
dstManager = graphics->getGraphicsCommands();
dstPool = graphics->getGraphicsCommands();
}
VkCommandBuffer sourceCmd = sourceManager->getCommands()->getHandle();
VkCommandBuffer destCmd = dstManager->getCommands()->getHandle();
VkCommandBuffer sourceCmd = sourcePool->getCommands()->getHandle();
VkCommandBuffer destCmd = dstPool->getCommands()->getHandle();
vkCmdPipelineBarrier(sourceCmd, srcStage, srcStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
vkCmdPipelineBarrier(destCmd, dstStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
currentOwner = newOwner;
sourceManager->submitCommands();
sourcePool->submitCommands();
}
void TextureHandle::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
void TextureBase::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
VkImageMemoryBarrier imageBarrier =
init::ImageMemoryBarrier(
image,
cast(layout),
cast(layout)
);
imageBarrier.srcAccessMask = srcAccess;
imageBarrier.dstAccessMask = dstAccess;
imageBarrier.subresourceRange = init::ImageSubresourceRange(aspect);
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
vkCmdPipelineBarrier(cmdBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
VkImageMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = srcAccess,
.dstAccessMask = dstAccess,
.oldLayout = cast(layout),
.newLayout = cast(layout),
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = image,
.subresourceRange = {
.aspectMask = aspect,
},
};
PCommand command = graphics->getQueueCommands(currentOwner)->getCommands();
vkCmdPipelineBarrier(command->getHandle(), srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &barrier);
}
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
: Gfx::Texture2D(graphics->getFamilyMapping(), createInfo.sourceData.owner)
, TextureBase(graphics, createInfo.elements > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
createInfo, Gfx::Texture2D::currentOwner, existingImage)
{
textureHandle = new TextureHandle(graphics, createInfo.bArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
createInfo, currentOwner, existingImage);
}
Texture2D::~Texture2D()
@@ -327,30 +347,30 @@ Texture2D::~Texture2D()
void Texture2D::changeLayout(Gfx::SeImageLayout newLayout)
{
textureHandle->changeLayout(newLayout);
TextureBase::changeLayout(newLayout);
}
void Texture2D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
{
textureHandle->download(mipLevel, arrayLayer, face, buffer);
TextureBase::download(mipLevel, arrayLayer, face, buffer);
}
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
textureHandle->executeOwnershipBarrier(newOwner);
TextureBase::executeOwnershipBarrier(newOwner);
}
void Texture2D::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
textureHandle->executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
: Gfx::Texture3D(graphics->getFamilyMapping(), createInfo.sourceData.owner)
, TextureBase(graphics, VK_IMAGE_VIEW_TYPE_3D,
createInfo, Gfx::Texture3D::currentOwner, existingImage)
{
textureHandle = new TextureHandle(graphics, VK_IMAGE_VIEW_TYPE_3D,
createInfo, currentOwner, existingImage);
}
Texture3D::~Texture3D()
@@ -359,29 +379,29 @@ Texture3D::~Texture3D()
void Texture3D::changeLayout(Gfx::SeImageLayout newLayout)
{
textureHandle->changeLayout(newLayout);
TextureBase::changeLayout(newLayout);
}
void Texture3D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
{
textureHandle->download(mipLevel, arrayLayer, face, buffer);
TextureBase::download(mipLevel, arrayLayer, face, buffer);
}
void Texture3D::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
textureHandle->executeOwnershipBarrier(newOwner);
TextureBase::executeOwnershipBarrier(newOwner);
}
void Texture3D::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
textureHandle->executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
TextureCube::TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
: Gfx::TextureCube(graphics->getFamilyMapping(), createInfo.sourceData.owner)
, TextureBase(graphics, createInfo.elements > 1? VK_IMAGE_VIEW_TYPE_CUBE_ARRAY : VK_IMAGE_VIEW_TYPE_CUBE,
createInfo, Gfx::TextureCube::currentOwner, existingImage)
{
textureHandle = new TextureHandle(graphics, createInfo.bArray ? VK_IMAGE_VIEW_TYPE_CUBE_ARRAY : VK_IMAGE_VIEW_TYPE_CUBE,
createInfo, currentOwner, existingImage);
}
TextureCube::~TextureCube()
@@ -390,20 +410,20 @@ TextureCube::~TextureCube()
void TextureCube::changeLayout(Gfx::SeImageLayout newLayout)
{
textureHandle->changeLayout(newLayout);
TextureBase::changeLayout(newLayout);
}
void TextureCube::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
{
textureHandle->download(mipLevel, arrayLayer, face, buffer);
TextureBase::download(mipLevel, arrayLayer, face, buffer);
}
void TextureCube::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
textureHandle->executeOwnershipBarrier(newOwner);
TextureBase::executeOwnershipBarrier(newOwner);
}
void TextureCube::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
textureHandle->executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
+36 -98
View File
@@ -8,46 +8,46 @@ namespace Seele
namespace Vulkan
{
class TextureHandle
class TextureBase
{
public:
TextureHandle(PGraphics graphics, VkImageViewType viewType,
TextureBase(PGraphics graphics, VkImageViewType viewType,
const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage = VK_NULL_HANDLE);
virtual ~TextureHandle();
virtual ~TextureBase();
inline VkImage getImage() const
constexpr VkImage getImage() const
{
return image;
}
inline VkImageView getView() const
constexpr VkImageView getView() const
{
return defaultView;
}
inline Gfx::SeImageLayout getLayout() const
constexpr Gfx::SeImageLayout getLayout() const
{
return layout;
}
inline VkImageAspectFlags getAspect() const
constexpr VkImageAspectFlags getAspect() const
{
return aspect;
}
inline VkImageUsageFlags getUsage() const
constexpr VkImageUsageFlags getUsage() const
{
return usage;
}
inline Gfx::SeFormat getFormat() const
constexpr Gfx::SeFormat getFormat() const
{
return format;
}
inline Gfx::SeSampleCountFlags getNumSamples() const
constexpr Gfx::SeSampleCountFlags getNumSamples() const
{
return samples;
}
inline uint32 getMipLevels() const
constexpr uint32 getMipLevels() const
{
return mipLevels;
}
inline bool isDepthStencil() const
constexpr bool isDepthStencil() const
{
return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
}
@@ -57,14 +57,14 @@ public:
void changeLayout(Gfx::SeImageLayout newLayout);
void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer);
private:
protected:
//Updates via reference
Gfx::QueueType& currentOwner;
PGraphics graphics;
OSubAllocation allocation;
uint32 sizeX;
uint32 sizeY;
uint32 sizeZ;
uint32 width;
uint32 height;
uint32 depth;
uint32 arrayCount;
uint32 layerCount;
uint32 mipLevels;
@@ -75,23 +75,9 @@ private:
VkImageView defaultView;
VkImageAspectFlags aspect;
Gfx::SeImageLayout layout;
friend class TextureBase;
friend class Texture2D;
friend class Texture3D;
friend class TextureCube;
friend class Graphics;
};
class TextureBase
{
public:
static TextureHandle* cast(Gfx::PTexture texture);
protected:
TextureHandle* textureHandle;
friend class Graphics;
};
DECLARE_REF(TextureBase)
class Texture2D : public Gfx::Texture2D, public TextureBase
{
public:
@@ -99,46 +85,31 @@ public:
virtual ~Texture2D();
virtual uint32 getWidth() const override
{
return textureHandle->sizeX;
return width;
}
virtual uint32 getHeight() const override
{
return textureHandle->sizeY;
return height;
}
virtual uint32 getDepth() const override
{
return textureHandle->sizeZ;
return depth;
}
virtual Gfx::SeFormat getFormat() const override
{
return textureHandle->format;
return format;
}
virtual Gfx::SeSampleCountFlags getNumSamples() const override
{
return textureHandle->getNumSamples();
return samples;
}
virtual uint32 getMipLevels() const override
{
return textureHandle->getMipLevels();
return mipLevels;
}
virtual void changeLayout(Gfx::SeImageLayout newLayout) override;
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
virtual void* getNativeHandle() override
{
return textureHandle;
}
inline VkImage getHandle() const
{
return textureHandle->image;
}
inline VkImageView getView() const
{
return textureHandle->defaultView;
}
inline bool isDepthStencil() const
{
return textureHandle->isDepthStencil();
}
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
@@ -155,46 +126,31 @@ public:
virtual ~Texture3D();
virtual uint32 getWidth() const override
{
return textureHandle->sizeX;
return width;
}
virtual uint32 getHeight() const override
{
return textureHandle->sizeY;
return height;
}
virtual uint32 getDepth() const override
{
return textureHandle->sizeZ;
return depth;
}
virtual Gfx::SeFormat getFormat() const override
{
return textureHandle->format;
return format;
}
virtual Gfx::SeSampleCountFlags getNumSamples() const override
{
return textureHandle->getNumSamples();
return samples;
}
virtual uint32 getMipLevels() const override
{
return textureHandle->getMipLevels();
return mipLevels;
}
virtual void changeLayout(Gfx::SeImageLayout newLayout) override;
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
virtual void* getNativeHandle() override
{
return textureHandle;
}
inline VkImage getHandle() const
{
return textureHandle->image;
}
inline VkImageView getView() const
{
return textureHandle->defaultView;
}
inline bool isDepthStencil() const
{
return textureHandle->isDepthStencil();
}
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
@@ -211,54 +167,36 @@ public:
virtual ~TextureCube();
virtual uint32 getWidth() const override
{
return textureHandle->sizeX;
return width;
}
virtual uint32 getHeight() const override
{
return textureHandle->sizeY;
return height;
}
virtual uint32 getDepth() const override
{
return textureHandle->sizeZ;
return depth;
}
virtual Gfx::SeFormat getFormat() const override
{
return textureHandle->format;
return format;
}
virtual Gfx::SeSampleCountFlags getNumSamples() const override
{
return textureHandle->getNumSamples();
return samples;
}
virtual uint32 getMipLevels() const override
{
return textureHandle->getMipLevels();
return mipLevels;
}
virtual void changeLayout(Gfx::SeImageLayout newLayout) override;
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
virtual void* getNativeHandle() override
{
return textureHandle;
}
inline VkImage getHandle() const
{
return textureHandle->image;
}
inline VkImageView getView() const
{
return textureHandle->defaultView;
}
inline bool isDepthStencil() const
{
return textureHandle->isDepthStencil();
}
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
};
DEFINE_REF(TextureCube)
}
}
+1
View File
@@ -2,6 +2,7 @@
#include "Window/WindowManager.h"
#include "MaterialInstance.h"
#include "Graphics/Graphics.h"
#include "Graphics/Shader.h"
using namespace Seele;
+2 -2
View File
@@ -223,7 +223,7 @@ void SamplerParameter::save(ArchiveBuffer& buffer) const
void SamplerParameter::load(ArchiveBuffer& buffer)
{
ShaderParameter::load(buffer);
data = buffer.getGraphics()->createSamplerState({});
data = buffer.getGraphics()->createSampler({});
}
CombinedTextureParameter::CombinedTextureParameter(std::string name, uint32 byteOffset, uint32 binding)
@@ -260,7 +260,7 @@ void CombinedTextureParameter::load(ArchiveBuffer& buffer)
std::string filename;
Serialization::load(buffer, filename);
data = AssetRegistry::findTexture(filename);
sampler = buffer.getGraphics()->createSamplerState({});
sampler = buffer.getGraphics()->createSampler({});
}
ConstantExpression::ConstantExpression()
+3 -3
View File
@@ -105,11 +105,11 @@ struct TextureParameter : public ShaderParameter
virtual void load(ArchiveBuffer& buffer) override;
};
DEFINE_REF(TextureParameter)
DECLARE_NAME_REF(Gfx, SamplerState)
DECLARE_NAME_REF(Gfx, Sampler)
struct SamplerParameter : public ShaderParameter
{
static constexpr uint64 IDENTIFIER = 0x08;
Gfx::OSamplerState data;
Gfx::OSampler data;
SamplerParameter() {}
SamplerParameter(std::string name, uint32 byteOffset, uint32 binding);
virtual ~SamplerParameter();
@@ -124,7 +124,7 @@ struct CombinedTextureParameter : public ShaderParameter
{
static constexpr uint64 IDENTIFIER = 0x10;
PTextureAsset data;
Gfx::PSamplerState sampler;
Gfx::PSampler sampler;
CombinedTextureParameter() {}
CombinedTextureParameter(std::string name, uint32 byteOffset, uint32 binding);
virtual ~CombinedTextureParameter();
+2 -2
View File
@@ -23,7 +23,7 @@ LightEnvironment::LightEnvironment(Gfx::PGraphics graphics)
.size = sizeof(Component::DirectionalLight) * MAX_DIRECTIONAL_LIGHTS,
.data = nullptr,
},
.stride = sizeof(Component::DirectionalLight),
.numElements = MAX_DIRECTIONAL_LIGHTS,
.dynamic = true,
});
pointLights = graphics->createShaderBuffer(ShaderBufferCreateInfo{
@@ -31,7 +31,7 @@ LightEnvironment::LightEnvironment(Gfx::PGraphics graphics)
.size = sizeof(Component::PointLight) * MAX_POINT_LIGHTS,
.data = nullptr,
},
.stride = sizeof(Component::PointLight),
.numElements = MAX_POINT_LIGHTS,
.dynamic = true,
});
}