compiles again
This commit is contained in:
@@ -193,28 +193,28 @@ void AssetRegistry::peekAsset(ArchiveBuffer& buffer)
|
||||
|
||||
AssetFolder* folder = getOrCreateFolder(folderPath);
|
||||
|
||||
PAsset asset;
|
||||
OAsset asset;
|
||||
switch (identifier)
|
||||
{
|
||||
case TextureAsset::IDENTIFIER:
|
||||
asset = new TextureAsset(folderPath, name);
|
||||
folder->textures[asset->getName()] = asset;
|
||||
folder->textures[name] = std::move(asset);
|
||||
break;
|
||||
case MeshAsset::IDENTIFIER:
|
||||
asset = new MeshAsset(folderPath, name);
|
||||
folder->meshes[asset->getName()] = asset;
|
||||
folder->meshes[name] = std::move(asset);
|
||||
break;
|
||||
case MaterialAsset::IDENTIFIER:
|
||||
asset = new MaterialAsset(folderPath, name);
|
||||
folder->materials[asset->getName()] = asset;
|
||||
folder->materials[name] = std::move(asset);
|
||||
break;
|
||||
case MaterialInstanceAsset::IDENTIFIER:
|
||||
asset = new MaterialInstanceAsset(folderPath, name);
|
||||
// TODO
|
||||
folder->instances[name] = std::move(asset);
|
||||
break;
|
||||
case FontAsset::IDENTIFIER:
|
||||
asset = new FontAsset(folderPath, name);
|
||||
folder->fonts[asset->getName()] = asset;
|
||||
folder->fonts[name] = std::move(asset);
|
||||
break;
|
||||
default:
|
||||
throw new std::logic_error("Unknown Identifier");
|
||||
@@ -241,20 +241,19 @@ void AssetRegistry::loadAsset(ArchiveBuffer& buffer)
|
||||
switch (identifier)
|
||||
{
|
||||
case TextureAsset::IDENTIFIER:
|
||||
asset = folder->textures.at(name);
|
||||
asset = PTextureAsset(folder->textures.at(name));
|
||||
break;
|
||||
case MeshAsset::IDENTIFIER:
|
||||
asset = folder->meshes.at(name);
|
||||
asset = PMeshAsset(folder->meshes.at(name));
|
||||
break;
|
||||
case MaterialAsset::IDENTIFIER:
|
||||
asset = folder->materials.at(name);
|
||||
asset = PMaterialAsset(folder->materials.at(name));
|
||||
break;
|
||||
case MaterialInstanceAsset::IDENTIFIER:
|
||||
//asset = new MaterialInstanceAsset(path);
|
||||
// TODO
|
||||
asset = PMaterialInstanceAsset(folder->instances.at(name));
|
||||
break;
|
||||
case FontAsset::IDENTIFIER:
|
||||
asset = folder->fonts.at(name);
|
||||
asset = PFontAsset(folder->fonts.at(name));
|
||||
break;
|
||||
default:
|
||||
throw new std::logic_error("Unknown Identifier");
|
||||
@@ -272,19 +271,23 @@ void AssetRegistry::saveFolder(const std::filesystem::path& folderPath, AssetFol
|
||||
std::filesystem::create_directory(rootFolder / folderPath);
|
||||
for (const auto& [name, texture] : folder->textures)
|
||||
{
|
||||
saveAsset(texture, TextureAsset::IDENTIFIER, folderPath, name);
|
||||
saveAsset(PTextureAsset(texture), TextureAsset::IDENTIFIER, folderPath, name);
|
||||
}
|
||||
for (const auto& [name, mesh] : folder->meshes)
|
||||
{
|
||||
saveAsset(mesh, MeshAsset::IDENTIFIER, folderPath, name);
|
||||
saveAsset(PMeshAsset(mesh), MeshAsset::IDENTIFIER, folderPath, name);
|
||||
}
|
||||
for (const auto& [name, material] : folder->materials)
|
||||
{
|
||||
saveAsset(material, MaterialAsset::IDENTIFIER, folderPath, name);
|
||||
saveAsset(PMaterialAsset(material), MaterialAsset::IDENTIFIER, folderPath, name);
|
||||
}
|
||||
for (const auto& [name, material] : folder->instances)
|
||||
{
|
||||
saveAsset(PMaterialInstanceAsset(material), MaterialInstanceAsset::IDENTIFIER, folderPath, name);
|
||||
}
|
||||
for (const auto& [name, font] : folder->fonts)
|
||||
{
|
||||
saveAsset(font, FontAsset::IDENTIFIER, folderPath, name);
|
||||
saveAsset(PFontAsset(font), FontAsset::IDENTIFIER, folderPath, name);
|
||||
}
|
||||
for (auto& [name, child] : folder->children)
|
||||
{
|
||||
@@ -316,28 +319,34 @@ std::filesystem::path AssetRegistry::getRootFolder()
|
||||
return get().rootFolder;
|
||||
}
|
||||
|
||||
void AssetRegistry::registerMesh(PMeshAsset mesh)
|
||||
void AssetRegistry::registerMesh(OMeshAsset mesh)
|
||||
{
|
||||
AssetFolder* folder = getOrCreateFolder(mesh->getFolderPath());
|
||||
folder->meshes[mesh->getName()] = mesh;
|
||||
folder->meshes[mesh->getName()] = std::move(mesh);
|
||||
}
|
||||
|
||||
void AssetRegistry::registerTexture(PTextureAsset texture)
|
||||
void AssetRegistry::registerTexture(OTextureAsset texture)
|
||||
{
|
||||
AssetFolder* folder = getOrCreateFolder(texture->getFolderPath());
|
||||
folder->textures[texture->getName()] = texture;
|
||||
folder->textures[texture->getName()] = std::move(texture);
|
||||
}
|
||||
|
||||
void AssetRegistry::registerFont(PFontAsset font)
|
||||
void AssetRegistry::registerFont(OFontAsset font)
|
||||
{
|
||||
AssetFolder* folder = getOrCreateFolder(font->getFolderPath());
|
||||
folder->fonts[font->getName()] = font;
|
||||
folder->fonts[font->getName()] = std::move(font);
|
||||
}
|
||||
|
||||
void AssetRegistry::registerMaterial(PMaterialAsset material)
|
||||
void AssetRegistry::registerMaterial(OMaterialAsset material)
|
||||
{
|
||||
AssetFolder* folder = getOrCreateFolder(material->getFolderPath());
|
||||
folder->materials[material->getName()] = material;
|
||||
folder->materials[material->getName()] = std::move(material);
|
||||
}
|
||||
|
||||
void AssetRegistry::registerMaterialInstance(OMaterialInstanceAsset material)
|
||||
{
|
||||
AssetFolder* folder = getOrCreateFolder(material->getFolderPath());
|
||||
folder->instances[material->getName()] = std::move(material);
|
||||
}
|
||||
|
||||
AssetRegistry::AssetFolder* AssetRegistry::getOrCreateFolder(std::string fullPath)
|
||||
|
||||
@@ -10,8 +10,8 @@ DECLARE_REF(TextureAsset)
|
||||
DECLARE_REF(FontAsset)
|
||||
DECLARE_REF(MeshAsset)
|
||||
DECLARE_REF(MaterialAsset)
|
||||
DECLARE_REF(MaterialInstanceAsset)
|
||||
DECLARE_NAME_REF(Gfx, Graphics)
|
||||
|
||||
class AssetRegistry
|
||||
{
|
||||
public:
|
||||
@@ -24,6 +24,7 @@ public:
|
||||
static PTextureAsset findTexture(const std::string& filePath);
|
||||
static PFontAsset findFont(const std::string& name);
|
||||
static PMaterialAsset findMaterial(const std::string& filePath);
|
||||
static PMaterialInstanceAsset findMaterialInstance(const std::string& filePath);
|
||||
|
||||
static std::ofstream createWriteStream(const std::filesystem::path& relativePath, std::ios_base::openmode openmode = std::ios::out);
|
||||
static std::ifstream createReadStream(const std::filesystem::path& relativePath, std::ios_base::openmode openmode = std::ios::in);
|
||||
@@ -36,10 +37,11 @@ public:
|
||||
{
|
||||
std::string folderPath;
|
||||
Map<std::string, AssetFolder*> children;
|
||||
Map<std::string, PTextureAsset> textures;
|
||||
Map<std::string, PFontAsset> fonts;
|
||||
Map<std::string, PMeshAsset> meshes;
|
||||
Map<std::string, PMaterialAsset> materials;
|
||||
Map<std::string, OTextureAsset> textures;
|
||||
Map<std::string, OFontAsset> fonts;
|
||||
Map<std::string, OMeshAsset> meshes;
|
||||
Map<std::string, OMaterialAsset> materials;
|
||||
Map<std::string, OMaterialInstanceAsset> instances;
|
||||
AssetFolder(std::string_view folderPath);
|
||||
~AssetFolder();
|
||||
};
|
||||
@@ -59,10 +61,11 @@ private:
|
||||
void saveFolder(const std::filesystem::path& folderPath, AssetFolder* folder);
|
||||
void saveAsset(PAsset asset, uint64 identifier, const std::filesystem::path& folderPath, std::string name);
|
||||
|
||||
void registerMesh(PMeshAsset mesh);
|
||||
void registerTexture(PTextureAsset texture);
|
||||
void registerFont(PFontAsset font);
|
||||
void registerMaterial(PMaterialAsset material);
|
||||
void registerMesh(OMeshAsset mesh);
|
||||
void registerTexture(OTextureAsset texture);
|
||||
void registerFont(OFontAsset font);
|
||||
void registerMaterial(OMaterialAsset material);
|
||||
void registerMaterialInstance(OMaterialInstanceAsset instance);
|
||||
|
||||
std::ofstream internalCreateWriteStream(const std::filesystem::path& relativePath, std::ios_base::openmode openmode = std::ios::out);
|
||||
std::ifstream internalCreateReadStream(const std::filesystem::path& relaitvePath, std::ios_base::openmode openmode = std::ios::in);
|
||||
|
||||
@@ -117,7 +117,9 @@ void FontAsset::load(ArchiveBuffer& buffer)
|
||||
.usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
|
||||
};
|
||||
|
||||
glyph.texture = buffer.getGraphics()->createTexture2D(createInfo);
|
||||
Gfx::OTexture2D texture = buffer.getGraphics()->createTexture2D(createInfo);
|
||||
glyph.texture = texture;
|
||||
usedTextures.add(std::move(texture));
|
||||
|
||||
ktxTexture_Destroy(ktxTexture(kTexture));
|
||||
|
||||
|
||||
@@ -18,13 +18,14 @@ public:
|
||||
|
||||
struct Glyph
|
||||
{
|
||||
Gfx::OTexture2D texture;
|
||||
Gfx::PTexture2D texture;
|
||||
IVector2 size;
|
||||
IVector2 bearing;
|
||||
uint32 advance;
|
||||
};
|
||||
const Map<uint32, Glyph> getGlyphData() const { return glyphs; }
|
||||
private:
|
||||
Array<Gfx::OTexture2D> usedTextures;
|
||||
Map<uint32, Glyph> glyphs;
|
||||
friend class FontLoader;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "MaterialAsset.h"
|
||||
#include "Material/Material.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "MaterialInstanceAsset.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
@@ -29,3 +30,13 @@ void MaterialAsset::load(ArchiveBuffer& buffer)
|
||||
material->compile();
|
||||
}
|
||||
|
||||
OMaterialInstanceAsset Seele::MaterialAsset::instantiate(const InstantiationParameter& params)
|
||||
{
|
||||
OMaterialInstance instance = material->instantiate();
|
||||
instance->setBaseMaterial(this);
|
||||
OMaterialInstanceAsset asset = new MaterialInstanceAsset(params.folderPath, params.name);
|
||||
asset->setHandle(std::move(instance));
|
||||
return asset;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_REF(Material)
|
||||
DECLARE_REF(MaterialInstanceAsset)
|
||||
struct InstantiationParameter
|
||||
{
|
||||
std::string name;
|
||||
std::string folderPath;
|
||||
};
|
||||
class MaterialAsset : public Asset
|
||||
{
|
||||
public:
|
||||
@@ -14,8 +20,9 @@ public:
|
||||
virtual void save(ArchiveBuffer& buffer) const override;
|
||||
virtual void load(ArchiveBuffer& buffer) override;
|
||||
PMaterial getMaterial() const { return material; }
|
||||
OMaterialInstanceAsset instantiate(const InstantiationParameter& params);
|
||||
private:
|
||||
PMaterial material;
|
||||
OMaterial material;
|
||||
friend class MaterialLoader;
|
||||
};
|
||||
DEFINE_REF(MaterialAsset)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "Material/Material.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
@@ -21,8 +22,15 @@ MaterialInstanceAsset::~MaterialInstanceAsset()
|
||||
|
||||
void MaterialInstanceAsset::save(ArchiveBuffer& buffer) const
|
||||
{
|
||||
Serialization::save(buffer, baseMaterial->getAssetIdentifier());
|
||||
material->save(buffer);
|
||||
}
|
||||
|
||||
void MaterialInstanceAsset::load(ArchiveBuffer& buffer)
|
||||
{
|
||||
std::string id;
|
||||
Serialization::load(buffer, id);
|
||||
material->load(buffer);
|
||||
baseMaterial = AssetRegistry::findMaterial(id);
|
||||
material->setBaseMaterial(baseMaterial);
|
||||
}
|
||||
|
||||
@@ -13,8 +13,11 @@ public:
|
||||
virtual ~MaterialInstanceAsset();
|
||||
virtual void save(ArchiveBuffer& buffer) const override;
|
||||
virtual void load(ArchiveBuffer& buffer) override;
|
||||
void setHandle(OMaterialInstance handle) { material = std::move(handle); }
|
||||
void setBase(PMaterialAsset base) { baseMaterial = base; }
|
||||
private:
|
||||
PMaterialInstance material;
|
||||
OMaterialInstance material;
|
||||
PMaterialAsset baseMaterial;
|
||||
};
|
||||
DEFINE_REF(MaterialInstanceAsset)
|
||||
} // namespace Seele
|
||||
|
||||
@@ -16,7 +16,7 @@ public:
|
||||
virtual void save(ArchiveBuffer& buffer) const override;
|
||||
virtual void load(ArchiveBuffer& buffer) override;
|
||||
//Workaround while no editor
|
||||
Array<PMesh> meshes;
|
||||
Array<OMesh> meshes;
|
||||
Component::Collider physicsMesh;
|
||||
};
|
||||
DEFINE_REF(MeshAsset)
|
||||
|
||||
@@ -13,16 +13,16 @@ public:
|
||||
virtual ~TextureAsset();
|
||||
virtual void save(ArchiveBuffer& buffer) const override;
|
||||
virtual void load(ArchiveBuffer& buffer) override;
|
||||
void setTexture(Gfx::PTexture _texture)
|
||||
void setTexture(Gfx::OTexture _texture)
|
||||
{
|
||||
texture = _texture;
|
||||
texture = std::move(_texture);
|
||||
}
|
||||
Gfx::PTexture getTexture()
|
||||
{
|
||||
return texture;
|
||||
}
|
||||
private:
|
||||
Gfx::PTexture texture;
|
||||
Gfx::OTexture texture;
|
||||
friend class TextureLoader;
|
||||
};
|
||||
DEFINE_REF(TextureAsset)
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_NAME_REF(Gfx, Viewport)
|
||||
namespace Component
|
||||
{
|
||||
struct Camera
|
||||
@@ -24,7 +23,6 @@ struct Camera
|
||||
{
|
||||
return Vector(viewMatrix[3]);
|
||||
}
|
||||
void setViewport(Gfx::PViewport viewport);
|
||||
void mouseMove(float deltaX, float deltaY);
|
||||
void mouseScroll(float x);
|
||||
void moveX(float amount);
|
||||
|
||||
@@ -393,7 +393,8 @@ public:
|
||||
std::allocator_traits<allocator_type>::construct(allocator, &_data[arraySize++], arguments...);
|
||||
return _data[arraySize - 1];
|
||||
}
|
||||
template<std::predicate Pred>
|
||||
template<class Pred>
|
||||
requires std::predicate<Pred, value_type>
|
||||
constexpr void remove_if(Pred pred, bool keepOrder = true)
|
||||
{
|
||||
remove(find(pred), keepOrder);
|
||||
|
||||
@@ -272,6 +272,39 @@ public:
|
||||
return getNode(root)->pair.value;
|
||||
}
|
||||
|
||||
constexpr const mapped_type& operator[](const key_type& key) const
|
||||
{
|
||||
size_t it = root;
|
||||
while (!equal(getNode(it)->pair.key, key))
|
||||
{
|
||||
if (comp(key, getNode(it)->pair.key))
|
||||
{
|
||||
it = getNode(it)->leftChild;
|
||||
}
|
||||
else
|
||||
{
|
||||
it = getNode(it)->rightChild;
|
||||
}
|
||||
}
|
||||
return getNode(it)->pair.value;
|
||||
}
|
||||
constexpr const mapped_type& operator[](key_type&& key) const
|
||||
{
|
||||
size_t it = root;
|
||||
while (!equal(getNode(it)->pair.key, key))
|
||||
{
|
||||
if (comp(key, getNode(it)->pair.key))
|
||||
{
|
||||
it = getNode(it)->leftChild;
|
||||
}
|
||||
else
|
||||
{
|
||||
it = getNode(it)->rightChild;
|
||||
}
|
||||
}
|
||||
return getNode(it)->pair.value;
|
||||
}
|
||||
|
||||
constexpr mapped_type& at(const key_type& key)
|
||||
{
|
||||
root = splay(root, key);
|
||||
@@ -414,11 +447,11 @@ public:
|
||||
buffer.readBytes(&len, sizeof(uint64));
|
||||
for(uint64 i = 0; i < len; ++i)
|
||||
{
|
||||
K k;
|
||||
V v;
|
||||
K k = K();
|
||||
V v = V();
|
||||
Serialization::load(buffer, k);
|
||||
Serialization::load(buffer, v);
|
||||
this->operator[](k) = v;
|
||||
this->operator[](std::move(k)) = std::move(v);
|
||||
}
|
||||
}
|
||||
private:
|
||||
|
||||
@@ -19,8 +19,6 @@ target_sources(Engine
|
||||
Resources.cpp
|
||||
Shader.h
|
||||
Shader.cpp
|
||||
ShaderCompiler.h
|
||||
ShaderCompiler.cpp
|
||||
StaticMeshVertexData.h
|
||||
StaticMeshVertexData.cpp
|
||||
Texture.h
|
||||
@@ -40,7 +38,6 @@ target_sources(Engine
|
||||
RenderTarget.h
|
||||
Resources.h
|
||||
Shader.h
|
||||
ShaderCompiler.h
|
||||
StaticMeshVertexData.h
|
||||
Texture.h
|
||||
VertexData.h)
|
||||
|
||||
@@ -132,12 +132,12 @@ public:
|
||||
virtual ~PipelineLayout() {}
|
||||
virtual void create() = 0;
|
||||
virtual void reset() = 0;
|
||||
void addDescriptorLayout(uint32 setIndex, const PDescriptorLayout layout);
|
||||
void addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout);
|
||||
void addPushConstants(const SePushConstantRange& pushConstants);
|
||||
virtual uint32 getHash() const = 0;
|
||||
|
||||
protected:
|
||||
Array<const PDescriptorLayout> descriptorSetLayouts;
|
||||
Array<PDescriptorLayout> descriptorSetLayouts;
|
||||
Array<SePushConstantRange> pushConstants;
|
||||
};
|
||||
DEFINE_REF(PipelineLayout)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "GraphicsEnums.h"
|
||||
#include "Enums.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
@@ -173,12 +173,6 @@ static constexpr uint32 numVerticesPerMeshlet = 64;
|
||||
static constexpr uint32 numPrimitivesPerMeshlet = 126;
|
||||
double getCurrentFrameDelta();
|
||||
|
||||
enum class RenderPassType : uint8
|
||||
{
|
||||
DepthPrepass,
|
||||
BasePass
|
||||
};
|
||||
|
||||
enum class QueueType
|
||||
{
|
||||
GRAPHICS = 1,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "Graphics.h"
|
||||
#include "ShaderCompiler.h"
|
||||
#include "Shader.h"
|
||||
#include "Graphics.h"
|
||||
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
@@ -11,3 +12,4 @@ Graphics::Graphics()
|
||||
Graphics::~Graphics()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "MinimalEngine.h"
|
||||
#include "Resources.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "Shader.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
|
||||
@@ -1,48 +1,92 @@
|
||||
#include "Initializer.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Graphics;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
LegacyPipelineCreateInfo::LegacyPipelineCreateInfo()
|
||||
: topology(Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
|
||||
, multisampleState(MultisampleState{
|
||||
.samples = 1,
|
||||
})
|
||||
, rasterizationState(RasterizationState{
|
||||
.polygonMode = Gfx::SE_POLYGON_MODE_FILL,
|
||||
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
||||
.frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE,
|
||||
})
|
||||
, depthStencilState(DepthStencilState{
|
||||
.depthTestEnable = true,
|
||||
.depthWriteEnable = true,
|
||||
.stencilTestEnable = false,
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL,
|
||||
.minDepthBounds = 0.0f,
|
||||
.maxDepthBounds = 1.0f,
|
||||
})
|
||||
, colorBlend(ColorBlendState{
|
||||
.logicOpEnable = false,
|
||||
.attachmentCount = 0,
|
||||
.blendAttachments = {
|
||||
ColorBlendState::BlendAttachment{
|
||||
.colorWriteMask =
|
||||
Gfx::SE_COLOR_COMPONENT_R_BIT |
|
||||
Gfx::SE_COLOR_COMPONENT_G_BIT |
|
||||
Gfx::SE_COLOR_COMPONENT_B_BIT |
|
||||
Gfx::SE_COLOR_COMPONENT_A_BIT,
|
||||
}
|
||||
},
|
||||
.blendConstants = {
|
||||
1.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
},
|
||||
})
|
||||
, rasterizationState(RasterizationState{
|
||||
.polygonMode = Gfx::SE_POLYGON_MODE_FILL,
|
||||
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
||||
.frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE,
|
||||
})
|
||||
, depthStencilState(DepthStencilState{
|
||||
.depthTestEnable = true,
|
||||
.depthWriteEnable = true,
|
||||
.stencilTestEnable = false,
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL,
|
||||
.minDepthBounds = 0.0f,
|
||||
.maxDepthBounds = 1.0f,
|
||||
})
|
||||
, colorBlend(ColorBlendState{
|
||||
.logicOpEnable = false,
|
||||
.attachmentCount = 0,
|
||||
.blendAttachments = {
|
||||
ColorBlendState::BlendAttachment{
|
||||
.colorWriteMask =
|
||||
Gfx::SE_COLOR_COMPONENT_R_BIT |
|
||||
Gfx::SE_COLOR_COMPONENT_G_BIT |
|
||||
Gfx::SE_COLOR_COMPONENT_B_BIT |
|
||||
Gfx::SE_COLOR_COMPONENT_A_BIT,
|
||||
}
|
||||
},
|
||||
.blendConstants = {
|
||||
1.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
},
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
Seele::Gfx::LegacyPipelineCreateInfo::~LegacyPipelineCreateInfo()
|
||||
LegacyPipelineCreateInfo::~LegacyPipelineCreateInfo()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MeshPipelineCreateInfo::MeshPipelineCreateInfo()
|
||||
: multisampleState(MultisampleState{
|
||||
.samples = 1,
|
||||
})
|
||||
, rasterizationState(RasterizationState{
|
||||
.polygonMode = Gfx::SE_POLYGON_MODE_FILL,
|
||||
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
||||
.frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE,
|
||||
})
|
||||
, depthStencilState(DepthStencilState{
|
||||
.depthTestEnable = true,
|
||||
.depthWriteEnable = true,
|
||||
.stencilTestEnable = false,
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL,
|
||||
.minDepthBounds = 0.0f,
|
||||
.maxDepthBounds = 1.0f,
|
||||
})
|
||||
, colorBlend(ColorBlendState{
|
||||
.logicOpEnable = false,
|
||||
.attachmentCount = 0,
|
||||
.blendAttachments = {
|
||||
ColorBlendState::BlendAttachment{
|
||||
.colorWriteMask =
|
||||
Gfx::SE_COLOR_COMPONENT_R_BIT |
|
||||
Gfx::SE_COLOR_COMPONENT_G_BIT |
|
||||
Gfx::SE_COLOR_COMPONENT_B_BIT |
|
||||
Gfx::SE_COLOR_COMPONENT_A_BIT,
|
||||
}
|
||||
},
|
||||
.blendConstants = {
|
||||
1.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
},
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
MeshPipelineCreateInfo::~MeshPipelineCreateInfo()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "Enums.h"
|
||||
#include "Containers/Map.h"
|
||||
#include "Math/Math.h"
|
||||
#include "Shader.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -26,7 +25,7 @@ struct GraphicsInitializer
|
||||
, engineName("SeeleEngine")
|
||||
, windowLayoutFile(nullptr)
|
||||
, layers{"VK_LAYER_KHRONOS_validation"}
|
||||
, instanceExtensions{}
|
||||
, instanceExtensions{"VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME"}
|
||||
, deviceExtensions{"VK_KHR_swapchain"}
|
||||
, windowHandle(nullptr)
|
||||
{
|
||||
@@ -102,18 +101,17 @@ struct IndexBufferCreateInfo
|
||||
struct UniformBufferCreateInfo
|
||||
{
|
||||
DataSource sourceData = DataSource();
|
||||
uint8 bDynamic = 0;
|
||||
uint8 dynamic = 0;
|
||||
};
|
||||
struct ShaderBufferCreateInfo
|
||||
{
|
||||
DataSource sourceData = DataSource();
|
||||
uint32 stride;
|
||||
uint8 bDynamic = 0;
|
||||
uint8 dynamic = 0;
|
||||
};
|
||||
struct ShaderCreateInfo
|
||||
{
|
||||
std::string mainModule;
|
||||
//It's possible to input multiple source files for materials or vertexFactories
|
||||
Array<std::string> additionalModules;
|
||||
std::string name; // Debug info
|
||||
std::string entryPoint;
|
||||
@@ -136,7 +134,7 @@ struct VertexElement
|
||||
SeFormat vertexFormat;
|
||||
uint8 attributeIndex;
|
||||
uint8 stride;
|
||||
uint8 bInstanced = 0;
|
||||
uint8 instanced = 0;
|
||||
};
|
||||
static_assert(std::is_aggregate_v<VertexElement>);
|
||||
struct RasterizationState
|
||||
@@ -191,6 +189,11 @@ struct ColorBlendState
|
||||
float blendConstants[4];
|
||||
};
|
||||
DECLARE_REF(VertexDeclaration)
|
||||
DECLARE_REF(VertexShader)
|
||||
DECLARE_REF(TaskShader)
|
||||
DECLARE_REF(MeshShader)
|
||||
DECLARE_REF(FragmentShader)
|
||||
DECLARE_REF(ComputeShader)
|
||||
DECLARE_REF(RenderPass)
|
||||
DECLARE_REF(PipelineLayout)
|
||||
struct LegacyPipelineCreateInfo
|
||||
@@ -220,44 +223,8 @@ struct MeshPipelineCreateInfo
|
||||
RasterizationState rasterizationState;
|
||||
DepthStencilState depthStencilState;
|
||||
ColorBlendState colorBlend;
|
||||
MeshPipelineCreateInfo()
|
||||
: multisampleState(MultisampleState{
|
||||
.samples = 1,
|
||||
})
|
||||
, rasterizationState(RasterizationState{
|
||||
.polygonMode = Gfx::SE_POLYGON_MODE_FILL,
|
||||
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
||||
.frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE,
|
||||
})
|
||||
, depthStencilState(DepthStencilState{
|
||||
.depthTestEnable = true,
|
||||
.depthWriteEnable = true,
|
||||
.stencilTestEnable = false,
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL,
|
||||
.minDepthBounds = 0.0f,
|
||||
.maxDepthBounds = 1.0f,
|
||||
})
|
||||
, colorBlend(ColorBlendState{
|
||||
.logicOpEnable = false,
|
||||
.attachmentCount = 0,
|
||||
.blendAttachments = {
|
||||
ColorBlendState::BlendAttachment{
|
||||
.colorWriteMask =
|
||||
Gfx::SE_COLOR_COMPONENT_R_BIT |
|
||||
Gfx::SE_COLOR_COMPONENT_G_BIT |
|
||||
Gfx::SE_COLOR_COMPONENT_B_BIT |
|
||||
Gfx::SE_COLOR_COMPONENT_A_BIT,
|
||||
}
|
||||
},
|
||||
.blendConstants = {
|
||||
1.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
},
|
||||
})
|
||||
{
|
||||
}
|
||||
MeshPipelineCreateInfo();
|
||||
~MeshPipelineCreateInfo();
|
||||
};
|
||||
struct ComputePipelineCreateInfo
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ Mesh::~Mesh()
|
||||
{
|
||||
}
|
||||
|
||||
void Mesh::save(ArchiveBuffer& buffer)
|
||||
void Mesh::save(ArchiveBuffer& buffer) const
|
||||
{
|
||||
Serialization::save(buffer, vertexData->getTypeName());
|
||||
Serialization::save(buffer, vertexCount);
|
||||
|
||||
@@ -15,9 +15,23 @@ public:
|
||||
uint64 vertexCount;
|
||||
PMaterialInstance referencedMaterial;
|
||||
Array<Meshlet> meshlets;
|
||||
void save(ArchiveBuffer& buffer);
|
||||
void save(ArchiveBuffer& buffer) const;
|
||||
void load(ArchiveBuffer& buffer);
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(Mesh)
|
||||
namespace Serialization
|
||||
{
|
||||
template<>
|
||||
static void save(ArchiveBuffer& buffer, const OMesh& ptr)
|
||||
{
|
||||
ptr->save(buffer);
|
||||
}
|
||||
template<>
|
||||
static void load(ArchiveBuffer& buffer, OMesh& ptr)
|
||||
{
|
||||
ptr = new Mesh();
|
||||
ptr->load(buffer);
|
||||
}
|
||||
} // namespace Serialization
|
||||
} // namespace Seele
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "BasePass.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Shader.h"
|
||||
#include "Window/Window.h"
|
||||
#include "Component/Camera.h"
|
||||
#include "Component/Mesh.h"
|
||||
@@ -13,47 +14,25 @@ using namespace Seele;
|
||||
|
||||
BasePass::BasePass(Gfx::PGraphics graphics, PScene scene)
|
||||
: RenderPass(graphics, scene)
|
||||
, descriptorSets(4)
|
||||
, descriptorSets(6)
|
||||
{
|
||||
UniformBufferCreateInfo uniformInitializer;
|
||||
basePassLayout = graphics->createPipelineLayout();
|
||||
|
||||
lightLayout = graphics->createDescriptorLayout("LightLayout");
|
||||
|
||||
// Directional Lights
|
||||
lightLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
lightLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
// Point Lights
|
||||
lightLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
lightLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
// Light Index List
|
||||
lightLayout->addDescriptorBinding(4, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
// Light Grid
|
||||
lightLayout->addDescriptorBinding(5, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
|
||||
lightLayout->create();
|
||||
basePassLayout->addDescriptorLayout(INDEX_LIGHT_ENV, lightLayout);
|
||||
descriptorSets[INDEX_LIGHT_ENV] = lightLayout->allocateDescriptorSet();
|
||||
basePassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewParamsLayout);
|
||||
basePassLayout->addDescriptorLayout(INDEX_LIGHT_ENV, scene->getLightEnvironment()->getDescriptorLayout());
|
||||
|
||||
viewLayout = graphics->createDescriptorLayout("ViewLayout");
|
||||
viewLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
uniformInitializer.sourceData.size = sizeof(ViewParameter);
|
||||
uniformInitializer.sourceData.data = (uint8*)&viewParams;
|
||||
uniformInitializer.bDynamic = true;
|
||||
viewParamBuffer = graphics->createUniformBuffer(uniformInitializer);
|
||||
viewLayout->create();
|
||||
basePassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewLayout);
|
||||
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet();
|
||||
lightCullingLayout = graphics->createDescriptorLayout("BasePassLightCulling");
|
||||
// oLightIndexList
|
||||
lightCullingLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
// tLightIndexList
|
||||
lightCullingLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
// oLightGrid
|
||||
lightCullingLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
|
||||
// tLightGrid
|
||||
lightCullingLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
|
||||
lightCullingLayout->create();
|
||||
|
||||
sceneLayout = graphics->createDescriptorLayout("SceneLayout");
|
||||
sceneLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
sceneLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
sceneLayout->create();
|
||||
basePassLayout->addDescriptorLayout(INDEX_SCENE_DATA, sceneLayout);
|
||||
//basePassLayout->addPushConstants(Gfx::SePushConstantRange{
|
||||
// .stageFlags = (Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT),
|
||||
// .offset = 0,
|
||||
// .size = sizeof(uint32),
|
||||
//});
|
||||
basePassLayout->addDescriptorLayout(INDEX_LIGHT_CULLING, lightCullingLayout);
|
||||
}
|
||||
|
||||
BasePass::~BasePass()
|
||||
@@ -62,61 +41,95 @@ BasePass::~BasePass()
|
||||
|
||||
void BasePass::beginFrame(const Component::Camera& cam)
|
||||
{
|
||||
DataSource uniformUpdate;
|
||||
RenderPass::beginFrame(cam);
|
||||
|
||||
viewParams.viewMatrix = cam.getViewMatrix();
|
||||
viewParams.projectionMatrix = viewport->getProjectionMatrix();
|
||||
viewParams.cameraPosition = Vector4(cam.getCameraPosition(), 1);
|
||||
viewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
|
||||
uniformUpdate.size = sizeof(ViewParameter);
|
||||
uniformUpdate.data = (uint8*)&viewParams;
|
||||
viewParamBuffer->updateContents(uniformUpdate);
|
||||
viewLayout->reset();
|
||||
lightLayout->reset();
|
||||
|
||||
descriptorSets[INDEX_SCENE_DATA] = sceneLayout->allocateDescriptorSet();
|
||||
descriptorSets[INDEX_SCENE_DATA]->updateBuffer(0, passData.sceneDataBuffer);
|
||||
descriptorSets[INDEX_SCENE_DATA]->writeChanges();
|
||||
descriptorSets[INDEX_LIGHT_ENV] = lightLayout->allocateDescriptorSet();
|
||||
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet();
|
||||
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer);
|
||||
descriptorSets[INDEX_VIEW_PARAMS]->writeChanges();
|
||||
//std::cout << "BasePass beginFrame()" << std::endl;
|
||||
//co_return;
|
||||
lightCullingLayout->reset();
|
||||
descriptorSets[INDEX_VIEW_PARAMS] = viewParamsSet;
|
||||
descriptorSets[INDEX_LIGHT_ENV] = scene->getLightEnvironment()->getDescriptorSet();
|
||||
descriptorSets[INDEX_LIGHT_CULLING] = lightCullingLayout->allocateDescriptorSet();
|
||||
}
|
||||
|
||||
void BasePass::render()
|
||||
{
|
||||
oLightIndexList->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
oLightGrid->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
oLightIndexList->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
tLightIndexList->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
oLightGrid->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
tLightGrid->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
|
||||
descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(0, passData.lightEnv.directionalLights);
|
||||
descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(1, passData.lightEnv.numDirectional);
|
||||
descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(2, passData.lightEnv.pointLights);
|
||||
descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(3, passData.lightEnv.numPoints);
|
||||
descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(4, oLightIndexList);
|
||||
descriptorSets[INDEX_LIGHT_ENV]->updateTexture(5, oLightGrid);
|
||||
descriptorSets[INDEX_LIGHT_ENV]->writeChanges();
|
||||
descriptorSets[INDEX_LIGHT_CULLING]->updateBuffer(0, oLightIndexList);
|
||||
descriptorSets[INDEX_LIGHT_CULLING]->updateBuffer(1, tLightIndexList);
|
||||
descriptorSets[INDEX_LIGHT_CULLING]->updateTexture(2, oLightGrid);
|
||||
descriptorSets[INDEX_LIGHT_CULLING]->updateTexture(3, tLightGrid);
|
||||
descriptorSets[INDEX_LIGHT_CULLING]->writeChanges();
|
||||
|
||||
graphics->beginRenderPass(renderPass);
|
||||
for (const auto& meshBatch : passData.staticDrawList)
|
||||
Gfx::ShaderPermutation permutation;
|
||||
permutation.hasFragment = true;
|
||||
permutation.useMeshShading = true;
|
||||
permutation.hasTaskShader = true;
|
||||
std::memcpy(permutation.taskFile, "MeshletBasePass", std::strlen("MeshletBasePass"));
|
||||
std::memcpy(permutation.vertexMeshFile, "MeshletBasePass", std::strlen("MeshletBasePass"));
|
||||
std::memcpy(permutation.fragmentFile, "BasePass", std::strlen("BasePass"));
|
||||
for (VertexData* vertexData : VertexData::getList())
|
||||
{
|
||||
processor->processMeshBatch(meshBatch, viewport, renderPass, basePassLayout, primitiveLayout, descriptorSets);
|
||||
std::memcpy(permutation.vertexDataName, vertexData->getTypeName().c_str(), std::strlen(vertexData->getTypeName().c_str()));
|
||||
const auto& materials = vertexData->getMaterialData();
|
||||
for (const auto& [_, materialData] : materials)
|
||||
{
|
||||
// Create Pipeline(Material, VertexData)
|
||||
// Descriptors:
|
||||
// ViewData => global, static
|
||||
// LightEnv => global, static
|
||||
// LightCulling => global, static
|
||||
// Material => per material
|
||||
// VertexData => per meshtype
|
||||
// SceneData => per material instance
|
||||
|
||||
std::memcpy(permutation.materialName, materialData.material->getName().c_str(), std::strlen(materialData.material->getName().c_str()));
|
||||
Gfx::PermutationId id(permutation);
|
||||
|
||||
Gfx::PRenderCommand command = graphics->createRenderCommand("DepthRender");
|
||||
Gfx::OPipelineLayout layout = graphics->createPipelineLayout(basePassLayout);
|
||||
layout->addDescriptorLayout(INDEX_MATERIAL, materialData.material->getDescriptorLayout());
|
||||
layout->addDescriptorLayout(INDEX_VERTEX_DATA, vertexData->getVertexDataLayout());
|
||||
layout->addDescriptorLayout(INDEX_SCENE_DATA, vertexData->getInstanceDataLayout());
|
||||
layout->create();
|
||||
|
||||
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
||||
assert(collection != nullptr);
|
||||
Gfx::MeshPipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.taskShader = collection->taskShader;
|
||||
pipelineInfo.meshShader = collection->meshShader;
|
||||
pipelineInfo.fragmentShader = collection->fragmentShader;
|
||||
pipelineInfo.pipelineLayout = layout;
|
||||
pipelineInfo.renderPass = renderPass;
|
||||
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL;
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInfo);
|
||||
command->bindPipeline(pipeline);
|
||||
|
||||
descriptorSets[INDEX_VERTEX_DATA] = vertexData->getVertexDataSet();
|
||||
for (const auto& [_, instance] : materialData.instances)
|
||||
{
|
||||
descriptorSets[INDEX_MATERIAL] = instance.materialInstance->getDescriptorSet();
|
||||
descriptorSets[INDEX_SCENE_DATA] = instance.descriptorSet;
|
||||
command->bindDescriptor(descriptorSets);
|
||||
command->dispatch(instance.numMeshes, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
graphics->executeCommands(processor->getRenderCommands());
|
||||
graphics->endRenderPass();
|
||||
//std::cout << "BasePass render()" << std::endl;
|
||||
//co_return;
|
||||
}
|
||||
|
||||
void BasePass::endFrame()
|
||||
{
|
||||
//std::cout << "BasePass endFrame()" << std::endl;
|
||||
//co_return;
|
||||
}
|
||||
|
||||
void BasePass::publishOutputs()
|
||||
@@ -131,16 +144,14 @@ void BasePass::createRenderPass()
|
||||
depthAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD;
|
||||
colorAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
colorAttachment->storeOp = Gfx::SE_ATTACHMENT_STORE_OP_STORE;
|
||||
Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(colorAttachment, depthAttachment);
|
||||
renderPass = graphics->createRenderPass(layout, viewport);
|
||||
Gfx::ORenderTargetLayout layout = new Gfx::RenderTargetLayout(colorAttachment, depthAttachment);
|
||||
renderPass = graphics->createRenderPass(std::move(layout), viewport);
|
||||
oLightIndexList = resources->requestBuffer("LIGHTCULLING_OLIGHTLIST");
|
||||
tLightIndexList = resources->requestBuffer("LIGHTCULLING_TLIGHTLIST");
|
||||
oLightGrid = resources->requestTexture("LIGHTCULLING_OLIGHTGRID");
|
||||
tLightGrid = resources->requestTexture("LIGHTCULLING_TLIGHTGRID");
|
||||
}
|
||||
|
||||
void BasePass::modifyRenderPassMacros(Map<const char*, const char*>& defines)
|
||||
{
|
||||
defines["INDEX_LIGHT_ENV"] = "0";
|
||||
defines["INDEX_VIEW_PARAMS"] = "1";
|
||||
defines["INDEX_MATERIAL"] = "2";
|
||||
defines["INDEX_SCENE_DATA"] = "3";
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ class BasePass : public RenderPass
|
||||
{
|
||||
public:
|
||||
BasePass(Gfx::PGraphics graphics, PScene scene);
|
||||
BasePass(BasePass&&) = default;
|
||||
BasePass& operator=(BasePass&&) = default;
|
||||
virtual ~BasePass();
|
||||
virtual void beginFrame(const Component::Camera& cam) override;
|
||||
virtual void render() override;
|
||||
@@ -19,24 +21,26 @@ public:
|
||||
private:
|
||||
Gfx::PRenderTargetAttachment colorAttachment;
|
||||
Gfx::PTexture2D depthBuffer;
|
||||
Gfx::PShaderBuffer oLightIndexList;
|
||||
Gfx::PShaderBuffer tLightIndexList;
|
||||
Gfx::PTexture2D oLightGrid;
|
||||
Gfx::PTexture2D tLightGrid;
|
||||
|
||||
Array<Gfx::PDescriptorSet> descriptorSets;
|
||||
PCameraActor source;
|
||||
Gfx::OPipelineLayout basePassLayout;
|
||||
// Set 0: Light environment
|
||||
static constexpr uint32 INDEX_LIGHT_ENV = 0;
|
||||
Gfx::OShaderBuffer oLightIndexList;
|
||||
Gfx::OTexture oLightGrid;
|
||||
Gfx::ODescriptorLayout lightLayout;
|
||||
// Set 1: viewParameter
|
||||
static constexpr uint32 INDEX_VIEW_PARAMS = 1;
|
||||
Gfx::ODescriptorLayout viewLayout;
|
||||
Gfx::OUniformBuffer viewParamBuffer;
|
||||
// Set 2: materials, generated
|
||||
static constexpr uint32 INDEX_MATERIAL = 2;
|
||||
// Set 3: primitive scene data
|
||||
static constexpr uint32 INDEX_SCENE_DATA = 3;
|
||||
Gfx::ODescriptorLayout sceneLayout;
|
||||
// Set 0: viewParameter, provided by renderpass
|
||||
// Set 1: light environment, provided by lightenv
|
||||
static constexpr uint32 INDEX_LIGHT_ENV = 1;
|
||||
// Set 2: light culling data
|
||||
static constexpr uint32 INDEX_LIGHT_CULLING = 2;
|
||||
Gfx::ODescriptorLayout lightCullingLayout;
|
||||
// Set 3: material data, generated from material
|
||||
static constexpr uint32 INDEX_MATERIAL = 3;
|
||||
// Set 4: vertex buffers, provided by vertexdata
|
||||
static constexpr uint32 INDEX_VERTEX_DATA = 4;
|
||||
// Set 5: instance data, provided by vertexdata
|
||||
static constexpr uint32 INDEX_SCENE_DATA = 5;
|
||||
};
|
||||
DEFINE_REF(BasePass)
|
||||
} // namespace Seele
|
||||
|
||||
@@ -12,6 +12,7 @@ target_sources(Engine
|
||||
RenderGraphResources.h
|
||||
RenderGraphResources.cpp
|
||||
RenderPass.h
|
||||
RenderPass.cpp
|
||||
SkyboxRenderPass.h
|
||||
SkyboxRenderPass.cpp
|
||||
TextPass.h
|
||||
|
||||
@@ -16,128 +16,129 @@ void Seele::addDebugVertices(Array<DebugVertex> verts)
|
||||
gDebugVertices.addAll(verts);
|
||||
}
|
||||
|
||||
DebugPass::DebugPass(Gfx::PGraphics graphics)
|
||||
: RenderPass(graphics)
|
||||
{
|
||||
|
||||
}
|
||||
DebugPass::~DebugPass()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DebugPass::beginFrame(const Component::Camera& cam)
|
||||
{
|
||||
DataSource uniformUpdate;
|
||||
|
||||
viewParams.viewMatrix = cam.getViewMatrix();
|
||||
viewParams.projectionMatrix = viewport->getProjectionMatrix();
|
||||
viewParams.cameraPosition = Vector4(cam.getCameraPosition(), 1);
|
||||
viewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
|
||||
uniformUpdate.size = sizeof(ViewParameter);
|
||||
uniformUpdate.data = (uint8*)&viewParams;
|
||||
viewParamsBuffer->updateContents(uniformUpdate);
|
||||
descriptorLayout->reset();
|
||||
descriptorSet = descriptorLayout->allocateDescriptorSet();
|
||||
descriptorSet->updateBuffer(0, viewParamsBuffer);
|
||||
descriptorSet->writeChanges();
|
||||
|
||||
VertexBufferCreateInfo vertexBufferInfo = {
|
||||
.sourceData = {
|
||||
.size = sizeof(DebugVertex) * passData.vertices.size(),
|
||||
.data = (uint8*)passData.vertices.data(),
|
||||
},
|
||||
.vertexSize = sizeof(DebugVertex),
|
||||
.numVertices = (uint32)passData.vertices.size(),
|
||||
};
|
||||
debugVertices = graphics->createVertexBuffer(vertexBufferInfo);
|
||||
|
||||
}
|
||||
|
||||
void DebugPass::render()
|
||||
{
|
||||
graphics->beginRenderPass(renderPass);
|
||||
Gfx::PRenderCommand renderCommand = graphics->createRenderCommand("DebugRender");
|
||||
renderCommand->setViewport(viewport);
|
||||
renderCommand->bindPipeline(pipeline);
|
||||
renderCommand->bindDescriptor(descriptorSet);
|
||||
renderCommand->bindVertexBuffer({VertexInputStream(0, 0, debugVertices)});
|
||||
renderCommand->draw((uint32)passData.vertices.size(), 1, 0, 0);
|
||||
graphics->executeCommands(Array{renderCommand});
|
||||
graphics->endRenderPass();
|
||||
}
|
||||
|
||||
void DebugPass::endFrame()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DebugPass::publishOutputs()
|
||||
{
|
||||
UniformBufferCreateInfo viewCreateInfo = {
|
||||
.sourceData = DataSource {
|
||||
.size = sizeof(ViewParameter),
|
||||
.data = nullptr,
|
||||
},
|
||||
.bDynamic = true
|
||||
};
|
||||
viewParamsBuffer = graphics->createUniformBuffer(viewCreateInfo);
|
||||
|
||||
descriptorLayout = graphics->createDescriptorLayout("DebugDescLayout");
|
||||
descriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
descriptorLayout->create();
|
||||
|
||||
pipelineLayout = graphics->createPipelineLayout();
|
||||
pipelineLayout->addDescriptorLayout(0, descriptorLayout);
|
||||
pipelineLayout->create();
|
||||
}
|
||||
|
||||
void DebugPass::createRenderPass()
|
||||
{
|
||||
Gfx::PRenderTargetAttachment baseColorAttachment = resources->requestRenderTarget("BASEPASS_COLOR");
|
||||
baseColorAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD;
|
||||
Gfx::PRenderTargetAttachment depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
|
||||
depthAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD;
|
||||
Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(baseColorAttachment, depthAttachment);
|
||||
renderPass = graphics->createRenderPass(layout, viewport);
|
||||
|
||||
ShaderCreateInfo createInfo;
|
||||
createInfo.name = "DebugVertex";
|
||||
createInfo.mainModule = "Debug";
|
||||
createInfo.entryPoint = "vertexMain";
|
||||
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
|
||||
Gfx::PVertexShader vertexShader = graphics->createVertexShader(createInfo);
|
||||
|
||||
createInfo.name = "DebugFragment";
|
||||
|
||||
createInfo.entryPoint = "fragmentMain";
|
||||
Gfx::PFragmentShader fragmentShader = graphics->createFragmentShader(createInfo);
|
||||
|
||||
Gfx::PVertexDeclaration vertexDecl = graphics->createVertexDeclaration({
|
||||
Gfx::VertexElement {
|
||||
.streamIndex = 0,
|
||||
.offset = offsetof(DebugVertex, position),
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
|
||||
.attributeIndex = 0,
|
||||
.stride = sizeof(DebugVertex),
|
||||
},
|
||||
Gfx::VertexElement {
|
||||
.streamIndex = 0,
|
||||
.offset = offsetof(DebugVertex, color),
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
|
||||
.attributeIndex = 1,
|
||||
.stride = sizeof(DebugVertex),
|
||||
}
|
||||
});
|
||||
|
||||
GraphicsPipelineCreateInfo gfxInfo;
|
||||
gfxInfo.vertexDeclaration = vertexDecl;
|
||||
gfxInfo.vertexShader = vertexShader;
|
||||
gfxInfo.fragmentShader = fragmentShader;
|
||||
gfxInfo.rasterizationState.polygonMode = Gfx::SE_POLYGON_MODE_LINE;
|
||||
gfxInfo.rasterizationState.lineWidth = 5.f;
|
||||
gfxInfo.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_LINE_LIST;
|
||||
gfxInfo.pipelineLayout = pipelineLayout;
|
||||
gfxInfo.renderPass = renderPass;
|
||||
pipeline = graphics->createGraphicsPipeline(gfxInfo);
|
||||
}
|
||||
//DebugPass::DebugPass(Gfx::PGraphics graphics, PScene scene)
|
||||
// : RenderPass(graphics, scene)
|
||||
//{
|
||||
//
|
||||
//}
|
||||
//DebugPass::~DebugPass()
|
||||
//{
|
||||
//
|
||||
//}
|
||||
//
|
||||
//void DebugPass::beginFrame(const Component::Camera& cam)
|
||||
//{
|
||||
// RenderPass::beginFrame(cam);
|
||||
// DataSource uniformUpdate;
|
||||
//
|
||||
// viewParams.viewMatrix = cam.getViewMatrix();
|
||||
// viewParams.projectionMatrix = viewport->getProjectionMatrix();
|
||||
// viewParams.cameraPosition = Vector4(cam.getCameraPosition(), 1);
|
||||
// viewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
|
||||
// uniformUpdate.size = sizeof(ViewParameter);
|
||||
// uniformUpdate.data = (uint8*)&viewParams;
|
||||
// viewParamsBuffer->updateContents(uniformUpdate);
|
||||
// descriptorLayout->reset();
|
||||
// descriptorSet = descriptorLayout->allocateDescriptorSet();
|
||||
// descriptorSet->updateBuffer(0, viewParamsBuffer);
|
||||
// descriptorSet->writeChanges();
|
||||
//
|
||||
// VertexBufferCreateInfo vertexBufferInfo = {
|
||||
// .sourceData = {
|
||||
// .size = sizeof(DebugVertex) * passData.vertices.size(),
|
||||
// .data = (uint8*)passData.vertices.data(),
|
||||
// },
|
||||
// .vertexSize = sizeof(DebugVertex),
|
||||
// .numVertices = (uint32)passData.vertices.size(),
|
||||
// };
|
||||
// debugVertices = graphics->createVertexBuffer(vertexBufferInfo);
|
||||
//
|
||||
//}
|
||||
//
|
||||
//void DebugPass::render()
|
||||
//{
|
||||
// graphics->beginRenderPass(renderPass);
|
||||
// Gfx::PRenderCommand renderCommand = graphics->createRenderCommand("DebugRender");
|
||||
// renderCommand->setViewport(viewport);
|
||||
// renderCommand->bindPipeline(pipeline);
|
||||
// renderCommand->bindDescriptor(descriptorSet);
|
||||
// renderCommand->bindVertexBuffer({VertexInputStream(0, 0, debugVertices)});
|
||||
// renderCommand->draw((uint32)passData.vertices.size(), 1, 0, 0);
|
||||
// graphics->executeCommands(Array{renderCommand});
|
||||
// graphics->endRenderPass();
|
||||
//}
|
||||
//
|
||||
//void DebugPass::endFrame()
|
||||
//{
|
||||
//
|
||||
//}
|
||||
//
|
||||
//void DebugPass::publishOutputs()
|
||||
//{
|
||||
// UniformBufferCreateInfo viewCreateInfo = {
|
||||
// .sourceData = DataSource {
|
||||
// .size = sizeof(ViewParameter),
|
||||
// .data = nullptr,
|
||||
// },
|
||||
// .dynamic = true
|
||||
// };
|
||||
// viewParamsBuffer = graphics->createUniformBuffer(viewCreateInfo);
|
||||
//
|
||||
// descriptorLayout = graphics->createDescriptorLayout("DebugDescLayout");
|
||||
// descriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
// descriptorLayout->create();
|
||||
//
|
||||
// pipelineLayout = graphics->createPipelineLayout();
|
||||
// pipelineLayout->addDescriptorLayout(0, descriptorLayout);
|
||||
// pipelineLayout->create();
|
||||
//}
|
||||
//
|
||||
//void DebugPass::createRenderPass()
|
||||
//{
|
||||
// Gfx::PRenderTargetAttachment baseColorAttachment = resources->requestRenderTarget("BASEPASS_COLOR");
|
||||
// baseColorAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD;
|
||||
// Gfx::PRenderTargetAttachment depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
|
||||
// depthAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD;
|
||||
// Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(baseColorAttachment, depthAttachment);
|
||||
// renderPass = graphics->createRenderPass(layout, viewport);
|
||||
//
|
||||
// ShaderCreateInfo createInfo;
|
||||
// createInfo.name = "DebugVertex";
|
||||
// createInfo.mainModule = "Debug";
|
||||
// createInfo.entryPoint = "vertexMain";
|
||||
// createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
|
||||
// Gfx::PVertexShader vertexShader = graphics->createVertexShader(createInfo);
|
||||
//
|
||||
// createInfo.name = "DebugFragment";
|
||||
//
|
||||
// createInfo.entryPoint = "fragmentMain";
|
||||
// Gfx::PFragmentShader fragmentShader = graphics->createFragmentShader(createInfo);
|
||||
//
|
||||
// Gfx::PVertexDeclaration vertexDecl = graphics->createVertexDeclaration({
|
||||
// Gfx::VertexElement {
|
||||
// .streamIndex = 0,
|
||||
// .offset = offsetof(DebugVertex, position),
|
||||
// .vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
|
||||
// .attributeIndex = 0,
|
||||
// .stride = sizeof(DebugVertex),
|
||||
// },
|
||||
// Gfx::VertexElement {
|
||||
// .streamIndex = 0,
|
||||
// .offset = offsetof(DebugVertex, color),
|
||||
// .vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
|
||||
// .attributeIndex = 1,
|
||||
// .stride = sizeof(DebugVertex),
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// GraphicsPipelineCreateInfo gfxInfo;
|
||||
// gfxInfo.vertexDeclaration = vertexDecl;
|
||||
// gfxInfo.vertexShader = vertexShader;
|
||||
// gfxInfo.fragmentShader = fragmentShader;
|
||||
// gfxInfo.rasterizationState.polygonMode = Gfx::SE_POLYGON_MODE_LINE;
|
||||
// gfxInfo.rasterizationState.lineWidth = 5.f;
|
||||
// gfxInfo.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_LINE_LIST;
|
||||
// gfxInfo.pipelineLayout = pipelineLayout;
|
||||
// gfxInfo.renderPass = renderPass;
|
||||
// pipeline = graphics->createGraphicsPipeline(gfxInfo);
|
||||
//}
|
||||
|
||||
@@ -11,7 +11,9 @@ DECLARE_REF(Viewport)
|
||||
class DebugPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
DebugPass(Gfx::PGraphics graphics);
|
||||
DebugPass(Gfx::PGraphics graphics, PScene scene);
|
||||
DebugPass(DebugPass&&) = default;
|
||||
DebugPass& operator=(DebugPass&&) = default;
|
||||
virtual ~DebugPass();
|
||||
virtual void beginFrame(const Component::Camera& cam) override;
|
||||
virtual void render() override;
|
||||
@@ -19,12 +21,12 @@ public:
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
private:
|
||||
Gfx::PVertexBuffer debugVertices;
|
||||
Gfx::PUniformBuffer viewParamsBuffer;
|
||||
Gfx::PDescriptorLayout descriptorLayout;
|
||||
Gfx::OVertexBuffer debugVertices;
|
||||
Gfx::OUniformBuffer viewParamsBuffer;
|
||||
Gfx::ODescriptorLayout descriptorLayout;
|
||||
Gfx::PDescriptorSet descriptorSet;
|
||||
Gfx::PPipelineLayout pipelineLayout;
|
||||
Gfx::PGraphicsPipeline pipeline;
|
||||
Gfx::OPipelineLayout pipelineLayout;
|
||||
Gfx::OGraphicsPipeline pipeline;
|
||||
};
|
||||
DEFINE_REF(DebugPass)
|
||||
} // namespace Seele
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "DepthPrepass.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Shader.h"
|
||||
#include "Window/Window.h"
|
||||
#include "Component/Camera.h"
|
||||
#include "Component/Mesh.h"
|
||||
@@ -16,15 +17,7 @@ DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene)
|
||||
UniformBufferCreateInfo uniformInitializer;
|
||||
|
||||
depthPrepassLayout = graphics->createPipelineLayout();
|
||||
|
||||
viewLayout = graphics->createDescriptorLayout("ViewLayout");
|
||||
viewLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
uniformInitializer.sourceData.size = sizeof(ViewParameter);
|
||||
uniformInitializer.sourceData.data = (uint8*)&viewParams;
|
||||
uniformInitializer.bDynamic = true;
|
||||
viewParamBuffer = graphics->createUniformBuffer(uniformInitializer);
|
||||
viewLayout->create();
|
||||
depthPrepassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewLayout);
|
||||
depthPrepassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewParamsLayout);
|
||||
}
|
||||
|
||||
DepthPrepass::~DepthPrepass()
|
||||
@@ -33,22 +26,8 @@ DepthPrepass::~DepthPrepass()
|
||||
|
||||
void DepthPrepass::beginFrame(const Component::Camera& cam)
|
||||
{
|
||||
DataSource uniformUpdate;
|
||||
|
||||
viewParams.viewMatrix = cam.getViewMatrix();
|
||||
viewParams.projectionMatrix = viewport->getProjectionMatrix();
|
||||
viewParams.cameraPosition = Vector4(cam.getCameraPosition(), 1);
|
||||
viewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
|
||||
uniformUpdate.size = sizeof(ViewParameter);
|
||||
uniformUpdate.data = (uint8*)&viewParams;
|
||||
viewParamBuffer->updateContents(uniformUpdate);
|
||||
viewLayout->reset();
|
||||
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet();
|
||||
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer);
|
||||
descriptorSets[INDEX_VIEW_PARAMS]->writeChanges();
|
||||
|
||||
//std::cout << "DepthPrepass beginFrame()" << std::endl;
|
||||
//co_return;
|
||||
RenderPass::beginFrame(cam);
|
||||
descriptorSets[INDEX_VIEW_PARAMS] = viewParamsSet;
|
||||
}
|
||||
|
||||
void DepthPrepass::render()
|
||||
@@ -57,9 +36,16 @@ void DepthPrepass::render()
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
|
||||
depthAttachment->getTexture()->transferOwnership(Gfx::QueueType::GRAPHICS);
|
||||
Gfx::ShaderPermutation permutation;
|
||||
permutation.hasFragment = false;
|
||||
permutation.useMeshShading = true;
|
||||
permutation.hasTaskShader = true;
|
||||
std::memcpy(permutation.taskFile, "MeshletBasePass", sizeof("MeshletBasePass"));
|
||||
std::memcpy(permutation.vertexMeshFile, "MeshletBasePass", sizeof("MeshletBasePass"));
|
||||
graphics->beginRenderPass(renderPass);
|
||||
for (VertexData* vertexData : VertexData::getList())
|
||||
{
|
||||
std::memcpy(permutation.vertexDataName, vertexData->getTypeName().c_str(), std::strlen(vertexData->getTypeName().c_str()));
|
||||
const auto& materials = vertexData->getMaterialData();
|
||||
for (const auto& [_, materialData] : materials)
|
||||
{
|
||||
@@ -69,6 +55,9 @@ void DepthPrepass::render()
|
||||
// Material => per material
|
||||
// VertexData => per meshtype
|
||||
// SceneData => per material instance
|
||||
std::memcpy(permutation.materialName, materialData.material->getName().c_str(), std::strlen(materialData.material->getName().c_str()));
|
||||
Gfx::PermutationId id(permutation);
|
||||
|
||||
Gfx::PRenderCommand command = graphics->createRenderCommand("DepthRender");
|
||||
Gfx::OPipelineLayout layout = graphics->createPipelineLayout(depthPrepassLayout);
|
||||
layout->addDescriptorLayout(INDEX_MATERIAL, materialData.material->getDescriptorLayout());
|
||||
@@ -91,14 +80,10 @@ void DepthPrepass::render()
|
||||
}
|
||||
}
|
||||
graphics->endRenderPass();
|
||||
//std::cout << "DepthPrepass render()" << std::endl;
|
||||
//co_return;
|
||||
}
|
||||
|
||||
void DepthPrepass::endFrame()
|
||||
{
|
||||
//std::cout << "DepthPrepass endFrame()" << std::endl;
|
||||
//co_return;
|
||||
}
|
||||
|
||||
void DepthPrepass::publishOutputs()
|
||||
@@ -119,8 +104,8 @@ void DepthPrepass::publishOutputs()
|
||||
|
||||
void DepthPrepass::createRenderPass()
|
||||
{
|
||||
Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(depthAttachment);
|
||||
renderPass = graphics->createRenderPass(layout, viewport);
|
||||
Gfx::ORenderTargetLayout layout = new Gfx::RenderTargetLayout(depthAttachment);
|
||||
renderPass = graphics->createRenderPass(std::move(layout), viewport);
|
||||
}
|
||||
|
||||
void DepthPrepass::modifyRenderPassMacros(Map<const char*, const char*>& defines)
|
||||
|
||||
@@ -8,7 +8,9 @@ class DepthPrepass : public RenderPass
|
||||
{
|
||||
public:
|
||||
DepthPrepass(Gfx::PGraphics graphics, PScene scene);
|
||||
~DepthPrepass();
|
||||
DepthPrepass(DepthPrepass&&) = default;
|
||||
DepthPrepass& operator=(DepthPrepass&&) = default;
|
||||
virtual ~DepthPrepass();
|
||||
virtual void beginFrame(const Component::Camera& cam) override;
|
||||
virtual void render() override;
|
||||
virtual void endFrame() override;
|
||||
@@ -23,15 +25,12 @@ private:
|
||||
|
||||
Gfx::OPipelineLayout depthPrepassLayout;
|
||||
// Set 0: viewParameter
|
||||
static constexpr uint32 INDEX_VIEW_PARAMS = 0;
|
||||
Gfx::ODescriptorLayout viewLayout;
|
||||
Gfx::OUniformBuffer viewParamBuffer;
|
||||
// Set 1: materials, generated
|
||||
static constexpr uint32 INDEX_MATERIAL = 1;
|
||||
constexpr static uint32 INDEX_MATERIAL = 1;
|
||||
// Set 2: vertices, from VertexData
|
||||
static constexpr uint32 INDEX_VERTEX_DATA = 2;
|
||||
constexpr static uint32 INDEX_VERTEX_DATA = 2;
|
||||
// Set 3: mesh data, either index buffer or meshlet data
|
||||
static constexpr uint32 INDEX_SCENE_DATA = 3;
|
||||
constexpr static uint32 INDEX_SCENE_DATA = 3;
|
||||
Gfx::ODescriptorLayout sceneDataLayout;
|
||||
};
|
||||
DEFINE_REF(DepthPrepass)
|
||||
|
||||
@@ -19,46 +19,30 @@ LightCullingPass::~LightCullingPass()
|
||||
|
||||
void LightCullingPass::beginFrame(const Component::Camera& cam)
|
||||
{
|
||||
RenderPass::beginFrame(cam);
|
||||
uint32_t viewportWidth = viewport->getSizeX();
|
||||
uint32_t viewportHeight = viewport->getSizeY();
|
||||
|
||||
DataSource uniformUpdate;
|
||||
viewParams.viewMatrix = cam.getViewMatrix();
|
||||
viewParams.projectionMatrix = viewport->getProjectionMatrix();
|
||||
viewParams.cameraPosition = Vector4(cam.getCameraPosition(), 1);
|
||||
viewParams.screenDimensions = Vector2(static_cast<float>(viewportWidth), static_cast<float>(viewportHeight));
|
||||
uniformUpdate.size = sizeof(ViewParameter);
|
||||
uniformUpdate.data = (uint8*)&viewParams;
|
||||
viewParamsBuffer->updateContents(uniformUpdate);
|
||||
|
||||
DataSource counterReset;
|
||||
uint32 reset = 0;
|
||||
counterReset.data = (uint8*)&reset;
|
||||
counterReset.size = sizeof(uint32);
|
||||
DataSource counterReset = {
|
||||
.size = sizeof(uint32),
|
||||
.data = (uint8*)&reset,
|
||||
};
|
||||
oLightIndexCounter->updateContents(counterReset);
|
||||
tLightIndexCounter->updateContents(counterReset);
|
||||
|
||||
cullingDescriptorLayout->reset();
|
||||
lightEnvDescriptorLayout->reset();
|
||||
cullingDescriptorSet = cullingDescriptorLayout->allocateDescriptorSet();
|
||||
lightEnvDescriptorSet = lightEnvDescriptorLayout->allocateDescriptorSet();
|
||||
|
||||
cullingDescriptorSet->updateBuffer(0, viewParamsBuffer);
|
||||
cullingDescriptorSet->updateBuffer(1, dispatchParamsBuffer);
|
||||
cullingDescriptorSet->updateBuffer(3, oLightIndexCounter);
|
||||
cullingDescriptorSet->updateBuffer(4, tLightIndexCounter);
|
||||
cullingDescriptorSet->updateBuffer(5, oLightIndexList);
|
||||
cullingDescriptorSet->updateBuffer(6, tLightIndexList);
|
||||
cullingDescriptorSet->updateTexture(7, oLightGrid);
|
||||
cullingDescriptorSet->updateTexture(8, tLightGrid);
|
||||
cullingDescriptorSet->updateBuffer(9, frustumBuffer);
|
||||
|
||||
|
||||
lightEnvDescriptorSet->updateBuffer(0, passData.lightEnv.directionalLights);
|
||||
lightEnvDescriptorSet->updateBuffer(1, passData.lightEnv.numDirectional);
|
||||
lightEnvDescriptorSet->updateBuffer(2, passData.lightEnv.pointLights);
|
||||
lightEnvDescriptorSet->updateBuffer(3, passData.lightEnv.numPoints);
|
||||
lightEnvDescriptorSet->writeChanges();
|
||||
cullingDescriptorSet->updateBuffer(0, dispatchParamsBuffer);
|
||||
cullingDescriptorSet->updateTexture(1, depthAttachment);
|
||||
cullingDescriptorSet->updateBuffer(2, oLightIndexCounter);
|
||||
cullingDescriptorSet->updateBuffer(3, tLightIndexCounter);
|
||||
cullingDescriptorSet->updateBuffer(4, oLightIndexList);
|
||||
cullingDescriptorSet->updateBuffer(5, tLightIndexList);
|
||||
cullingDescriptorSet->updateTexture(6, Gfx::PTexture2D(oLightGrid));
|
||||
cullingDescriptorSet->updateTexture(7, Gfx::PTexture2D(tLightGrid));
|
||||
cullingDescriptorSet->updateBuffer(8, frustumBuffer);
|
||||
//std::cout << "LightCulling beginFrame()" << std::endl;
|
||||
//co_return;
|
||||
}
|
||||
@@ -80,9 +64,8 @@ void LightCullingPass::render()
|
||||
cullingDescriptorSet->writeChanges();
|
||||
Gfx::PComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand");
|
||||
computeCommand->bindPipeline(cullingPipeline);
|
||||
Array<Gfx::PDescriptorSet> descriptorSets = {cullingDescriptorSet, lightEnvDescriptorSet};
|
||||
computeCommand->bindDescriptor(descriptorSets);
|
||||
//computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z);
|
||||
computeCommand->bindDescriptor({ viewParamsSet, lightEnv->getDescriptorSet(), cullingDescriptorSet });
|
||||
computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z);
|
||||
Array<Gfx::PComputeCommand> commands = {computeCommand};
|
||||
graphics->executeCommands(commands);
|
||||
depthAttachment->changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
@@ -105,42 +88,41 @@ void LightCullingPass::publishOutputs()
|
||||
glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1));
|
||||
dispatchParams.numThreadGroups = numThreadGroups;
|
||||
dispatchParams.numThreads = numThreadGroups * glm::uvec3(BLOCK_SIZE, BLOCK_SIZE, 1);
|
||||
dispatchParamsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = sizeof(DispatchParams),
|
||||
.data = (uint8*)&dispatchParams,
|
||||
},
|
||||
.dynamic = false,
|
||||
});
|
||||
|
||||
cullingDescriptorLayout = graphics->createDescriptorLayout("CullingLayout");
|
||||
|
||||
//ViewParams
|
||||
// Dispatchparams
|
||||
cullingDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
//Dispatchparams
|
||||
cullingDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
//DepthTexture
|
||||
cullingDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
|
||||
cullingDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
|
||||
//o_lightIndexCounter
|
||||
cullingDescriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
cullingDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
//t_lightIndexCounter
|
||||
cullingDescriptorLayout->addDescriptorBinding(4, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
cullingDescriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
//o_lightIndexList
|
||||
cullingDescriptorLayout->addDescriptorBinding(5, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
cullingDescriptorLayout->addDescriptorBinding(4, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
//t_lightIndexList
|
||||
cullingDescriptorLayout->addDescriptorBinding(6, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
cullingDescriptorLayout->addDescriptorBinding(5, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
//o_lightGrid
|
||||
cullingDescriptorLayout->addDescriptorBinding(7, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
|
||||
cullingDescriptorLayout->addDescriptorBinding(6, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
|
||||
//t_lightGrid
|
||||
cullingDescriptorLayout->addDescriptorBinding(8, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
|
||||
cullingDescriptorLayout->addDescriptorBinding(7, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
|
||||
//Frustums
|
||||
cullingDescriptorLayout->addDescriptorBinding(9, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, viewportWidth * viewportHeight);
|
||||
cullingDescriptorLayout->addDescriptorBinding(8, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, viewportWidth * viewportHeight);
|
||||
|
||||
|
||||
lightEnvDescriptorLayout = graphics->createDescriptorLayout("LightEnv");
|
||||
// Directional Lights
|
||||
lightEnvDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, MAX_DIRECTIONAL_LIGHTS);
|
||||
lightEnvDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
// Point Lights
|
||||
lightEnvDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, MAX_POINT_LIGHTS);
|
||||
lightEnvDescriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
lightEnv = scene->getLightEnvironment();
|
||||
|
||||
cullingLayout = graphics->createPipelineLayout();
|
||||
cullingLayout->addDescriptorLayout(0, cullingDescriptorLayout);
|
||||
cullingLayout->addDescriptorLayout(1, lightEnvDescriptorLayout);
|
||||
cullingLayout->addDescriptorLayout(0, viewParamsLayout);
|
||||
cullingLayout->addDescriptorLayout(1, lightEnv->getDescriptorLayout());
|
||||
cullingLayout->addDescriptorLayout(2, cullingDescriptorLayout);
|
||||
cullingLayout->create();
|
||||
|
||||
ShaderCreateInfo createInfo;
|
||||
@@ -148,9 +130,6 @@ void LightCullingPass::publishOutputs()
|
||||
|
||||
createInfo.mainModule = "LightCulling";
|
||||
createInfo.entryPoint = "cullLights";
|
||||
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
|
||||
createInfo.defines["INDEX_LIGHT_ENV"] = "1";
|
||||
createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "0";
|
||||
cullingShader = graphics->createComputeShader(createInfo);
|
||||
|
||||
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
||||
@@ -167,7 +146,7 @@ void LightCullingPass::publishOutputs()
|
||||
.owner = Gfx::QueueType::COMPUTE,
|
||||
},
|
||||
.stride = sizeof(uint32),
|
||||
.bDynamic = true,
|
||||
.dynamic = true,
|
||||
};
|
||||
oLightIndexCounter = graphics->createShaderBuffer(structInfo);
|
||||
tLightIndexCounter = graphics->createShaderBuffer(structInfo);
|
||||
@@ -181,7 +160,7 @@ void LightCullingPass::publishOutputs()
|
||||
.owner = Gfx::QueueType::COMPUTE
|
||||
},
|
||||
.stride = sizeof(uint32),
|
||||
.bDynamic = false,
|
||||
.dynamic = false,
|
||||
};
|
||||
oLightIndexList = graphics->createShaderBuffer(structInfo);
|
||||
tLightIndexList = graphics->createShaderBuffer(structInfo);
|
||||
@@ -197,8 +176,8 @@ void LightCullingPass::publishOutputs()
|
||||
oLightGrid = graphics->createTexture2D(textureInfo);
|
||||
tLightGrid = graphics->createTexture2D(textureInfo);
|
||||
|
||||
resources->registerTextureOutput("LIGHTCULLING_OLIGHTGRID", oLightGrid);
|
||||
resources->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", tLightGrid);
|
||||
resources->registerTextureOutput("LIGHTCULLING_OLIGHTGRID", Gfx::PTexture2D(oLightGrid));
|
||||
resources->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", Gfx::PTexture2D(tLightGrid));
|
||||
}
|
||||
|
||||
|
||||
@@ -219,28 +198,22 @@ void LightCullingPass::setupFrustums()
|
||||
glm::uvec3 numThreads = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1));
|
||||
glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1));
|
||||
|
||||
viewParams = {
|
||||
.viewMatrix = Matrix4(),
|
||||
.projectionMatrix = Matrix4(),
|
||||
.cameraPosition = Vector4(),
|
||||
.screenDimensions = glm::vec2(viewportWidth, viewportHeight),
|
||||
};
|
||||
RenderPass::beginFrame(Component::Camera());
|
||||
dispatchParams.numThreads = numThreads;
|
||||
dispatchParams.numThreadGroups = numThreadGroups;
|
||||
|
||||
Gfx::PDescriptorLayout frustumDescriptorLayout = graphics->createDescriptorLayout("FrustumLayout");
|
||||
Gfx::ODescriptorLayout frustumDescriptorLayout = graphics->createDescriptorLayout("FrustumLayout");
|
||||
frustumDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
frustumDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
frustumDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
frustumDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
frustumLayout = graphics->createPipelineLayout();
|
||||
frustumLayout->addDescriptorLayout(0, frustumDescriptorLayout);
|
||||
frustumLayout->addDescriptorLayout(0, viewParamsLayout);
|
||||
frustumLayout->addDescriptorLayout(1, frustumDescriptorLayout);
|
||||
frustumLayout->create();
|
||||
ShaderCreateInfo createInfo;
|
||||
createInfo.name = "Frustum";
|
||||
|
||||
createInfo.mainModule = "ComputeFrustums";
|
||||
createInfo.entryPoint = "computeFrustums";
|
||||
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
|
||||
frustumShader = graphics->createComputeShader(createInfo);
|
||||
|
||||
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
||||
@@ -248,40 +221,31 @@ void LightCullingPass::setupFrustums()
|
||||
pipelineInfo.pipelineLayout = frustumLayout;
|
||||
frustumPipeline = graphics->createComputePipeline(pipelineInfo);
|
||||
|
||||
DataSource resourceInfo;
|
||||
UniformBufferCreateInfo uniformInfo;
|
||||
resourceInfo.size = sizeof(ViewParameter);
|
||||
resourceInfo.data = (uint8*)&viewParams;
|
||||
resourceInfo.owner = Gfx::QueueType::COMPUTE;
|
||||
uniformInfo.sourceData = resourceInfo;
|
||||
uniformInfo.bDynamic = false;
|
||||
viewParamsBuffer = graphics->createUniformBuffer(uniformInfo);
|
||||
|
||||
resourceInfo.size = sizeof(DispatchParams);
|
||||
resourceInfo.data = (uint8*)&dispatchParams;
|
||||
uniformInfo.sourceData = resourceInfo;
|
||||
uniformInfo.bDynamic = false;
|
||||
dispatchParamsBuffer = graphics->createUniformBuffer(uniformInfo);
|
||||
|
||||
ShaderBufferCreateInfo structuredInfo = {
|
||||
Gfx::OUniformBuffer frustumDispatchParamsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = sizeof(DispatchParams),
|
||||
.data = (uint8*) & dispatchParams,
|
||||
},
|
||||
.dynamic = false,
|
||||
});
|
||||
|
||||
frustumBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = sizeof(Frustum) * numThreads.x * numThreads.y * numThreads.z,
|
||||
.data = nullptr,
|
||||
},
|
||||
.stride = sizeof(Frustum),
|
||||
.bDynamic = false,
|
||||
};
|
||||
frustumBuffer = graphics->createShaderBuffer(structuredInfo);
|
||||
.dynamic = false,
|
||||
});
|
||||
|
||||
frustumDescriptorSet = frustumDescriptorLayout->allocateDescriptorSet();
|
||||
frustumDescriptorSet->updateBuffer(0, viewParamsBuffer);
|
||||
frustumDescriptorSet->updateBuffer(1, dispatchParamsBuffer);
|
||||
frustumDescriptorSet->updateBuffer(2, frustumBuffer);
|
||||
frustumDescriptorSet->updateBuffer(0, frustumDispatchParamsBuffer);
|
||||
frustumDescriptorSet->updateBuffer(1, frustumBuffer);
|
||||
frustumDescriptorSet->writeChanges();
|
||||
|
||||
Gfx::PComputeCommand command = graphics->createComputeCommand("FrustumCommand");
|
||||
command->bindPipeline(frustumPipeline);
|
||||
command->bindDescriptor(frustumDescriptorSet);
|
||||
command->bindDescriptor({ viewParamsSet, frustumDescriptorSet });
|
||||
command->dispatch(numThreadGroups.x, numThreadGroups.y, numThreadGroups.z);
|
||||
Array<Gfx::PComputeCommand> commands = {command};
|
||||
graphics->executeCommands(commands);
|
||||
|
||||
@@ -12,6 +12,8 @@ class LightCullingPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
LightCullingPass(Gfx::PGraphics graphics, PScene scene);
|
||||
LightCullingPass(LightCullingPass&&) = default;
|
||||
LightCullingPass& operator=(LightCullingPass&&) = default;
|
||||
virtual ~LightCullingPass();
|
||||
virtual void beginFrame(const Component::Camera& cam) override;
|
||||
virtual void render() override;
|
||||
@@ -39,30 +41,29 @@ private:
|
||||
{
|
||||
Plane planes[4];
|
||||
};
|
||||
|
||||
Gfx::PShaderBuffer frustumBuffer;
|
||||
Gfx::PUniformBuffer dispatchParamsBuffer;
|
||||
Gfx::PUniformBuffer viewParamsBuffer;
|
||||
Gfx::PDescriptorSet frustumDescriptorSet;
|
||||
Gfx::PComputeShader frustumShader;
|
||||
Gfx::PPipelineLayout frustumLayout;
|
||||
Gfx::PComputePipeline frustumPipeline;
|
||||
|
||||
Gfx::OShaderBuffer frustumBuffer;
|
||||
Gfx::OUniformBuffer dispatchParamsBuffer;
|
||||
Gfx::OUniformBuffer viewParamsBuffer;
|
||||
Gfx::PDescriptorSet frustumDescriptorSet;
|
||||
Gfx::OComputeShader frustumShader;
|
||||
Gfx::OPipelineLayout frustumLayout;
|
||||
Gfx::OComputePipeline frustumPipeline;
|
||||
|
||||
PLightEnvironment lightEnv;
|
||||
Gfx::PTexture2D depthAttachment;
|
||||
Gfx::PShaderBuffer frustums;
|
||||
Gfx::PShaderBuffer oLightIndexCounter;
|
||||
Gfx::PShaderBuffer tLightIndexCounter;
|
||||
Gfx::PShaderBuffer oLightIndexList;
|
||||
Gfx::PShaderBuffer tLightIndexList;
|
||||
Gfx::PTexture2D oLightGrid;
|
||||
Gfx::PTexture2D tLightGrid;
|
||||
Gfx::PDescriptorSet lightEnvDescriptorSet;
|
||||
Gfx::OShaderBuffer frustums;
|
||||
Gfx::OShaderBuffer oLightIndexCounter;
|
||||
Gfx::OShaderBuffer tLightIndexCounter;
|
||||
Gfx::OShaderBuffer oLightIndexList;
|
||||
Gfx::OShaderBuffer tLightIndexList;
|
||||
Gfx::OTexture2D oLightGrid;
|
||||
Gfx::OTexture2D tLightGrid;
|
||||
Gfx::PDescriptorSet cullingDescriptorSet;
|
||||
Gfx::PDescriptorLayout lightEnvDescriptorLayout;
|
||||
Gfx::PDescriptorLayout cullingDescriptorLayout;
|
||||
Gfx::PComputeShader cullingShader;
|
||||
Gfx::PPipelineLayout cullingLayout;
|
||||
Gfx::PComputePipeline cullingPipeline;
|
||||
Gfx::ODescriptorLayout cullingDescriptorLayout;
|
||||
Gfx::OComputeShader cullingShader;
|
||||
Gfx::OPipelineLayout cullingLayout;
|
||||
Gfx::OComputePipeline cullingPipeline;
|
||||
};
|
||||
DEFINE_REF(LightCullingPass)
|
||||
} // namespace Seele
|
||||
|
||||
@@ -24,7 +24,7 @@ template<typename This, typename... Rest>
|
||||
class RenderGraph<This, Rest...> : private RenderGraph<Rest...>
|
||||
{
|
||||
public:
|
||||
RenderGraph(PRenderGraphResources resources, This&& pass, Rest&&... rest)
|
||||
RenderGraph(PRenderGraphResources resources, This pass, Rest... rest)
|
||||
: RenderGraph<Rest...>(resources, std::move(rest)...)
|
||||
, resources(resources)
|
||||
, rp(std::move(pass))
|
||||
@@ -83,7 +83,7 @@ class RenderGraphBuilder
|
||||
{
|
||||
public:
|
||||
template<typename... RenderPasses>
|
||||
static RenderGraph<RenderPasses...> build(RenderPasses&&... renderPasses)
|
||||
static RenderGraph<RenderPasses...> build(RenderPasses... renderPasses)
|
||||
{
|
||||
PRenderGraphResources resources = new RenderGraphResources();
|
||||
return RenderGraph<RenderPasses...>(resources, std::move(renderPasses)...);
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
#include "RenderPass.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
RenderPass::RenderPass(Gfx::PGraphics graphics, PScene scene)
|
||||
: graphics(graphics)
|
||||
, scene(scene)
|
||||
{
|
||||
|
||||
viewParamsLayout = graphics->createDescriptorLayout("ViewLayout");
|
||||
viewParamsLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
UniformBufferCreateInfo uniformInitializer = {
|
||||
.sourceData = {
|
||||
.size = sizeof(ViewParameter),
|
||||
.data = (uint8*)&viewParams,
|
||||
},
|
||||
.dynamic = true,
|
||||
};
|
||||
viewParamsBuffer = graphics->createUniformBuffer(uniformInitializer);
|
||||
viewParamsLayout->create();
|
||||
}
|
||||
|
||||
RenderPass::~RenderPass()
|
||||
{}
|
||||
|
||||
void RenderPass::beginFrame(const Component::Camera& cam)
|
||||
{
|
||||
viewParams = {
|
||||
.viewMatrix = cam.getViewMatrix(),
|
||||
.projectionMatrix = viewport->getProjectionMatrix(),
|
||||
.cameraPosition = Vector4(cam.getCameraPosition(), 1),
|
||||
.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY())),
|
||||
};
|
||||
DataSource uniformUpdate = {
|
||||
.size = sizeof(ViewParameter),
|
||||
.data = (uint8*)&viewParams,
|
||||
};
|
||||
viewParamsBuffer->updateContents(uniformUpdate);
|
||||
viewParamsLayout->reset();
|
||||
viewParamsSet = viewParamsLayout->allocateDescriptorSet();
|
||||
viewParamsSet->updateBuffer(0, viewParamsBuffer);
|
||||
viewParamsSet->writeChanges();
|
||||
}
|
||||
|
||||
void RenderPass::setResources(PRenderGraphResources _resources)
|
||||
{
|
||||
resources = _resources;
|
||||
}
|
||||
|
||||
void RenderPass::setViewport(Gfx::PViewport _viewport)
|
||||
{
|
||||
viewport = _viewport;
|
||||
publishOutputs();
|
||||
}
|
||||
@@ -15,23 +15,17 @@ DECLARE_NAME_REF(Gfx, RenderPass)
|
||||
class RenderPass
|
||||
{
|
||||
public:
|
||||
RenderPass(Gfx::PGraphics graphics, PScene scene)
|
||||
: graphics(graphics)
|
||||
, scene(scene)
|
||||
{}
|
||||
virtual ~RenderPass()
|
||||
{}
|
||||
virtual void beginFrame(const Component::Camera& cam) = 0;
|
||||
RenderPass(Gfx::PGraphics graphics, PScene scene);
|
||||
RenderPass(RenderPass&&) = default;
|
||||
RenderPass& operator=(RenderPass&&) = default;
|
||||
virtual ~RenderPass();
|
||||
virtual void beginFrame(const Component::Camera& cam);
|
||||
virtual void render() = 0;
|
||||
virtual void endFrame() = 0;
|
||||
virtual void publishOutputs() = 0;
|
||||
virtual void createRenderPass() = 0;
|
||||
void setResources(PRenderGraphResources _resources) { resources = _resources; }
|
||||
void setViewport(Gfx::PViewport _viewport)
|
||||
{
|
||||
viewport = _viewport;
|
||||
publishOutputs();
|
||||
}
|
||||
void setResources(PRenderGraphResources _resources);
|
||||
void setViewport(Gfx::PViewport _viewport);
|
||||
protected:
|
||||
struct ViewParameter
|
||||
{
|
||||
@@ -42,7 +36,11 @@ protected:
|
||||
Vector2 pad0;
|
||||
} viewParams;
|
||||
PRenderGraphResources resources;
|
||||
Gfx::PRenderPass renderPass;
|
||||
static constexpr uint32 INDEX_VIEW_PARAMS = 0;
|
||||
Gfx::ODescriptorLayout viewParamsLayout;
|
||||
Gfx::OShaderBuffer viewParamsBuffer;
|
||||
Gfx::PDescriptorSet viewParamsSet;
|
||||
Gfx::ORenderPass renderPass;
|
||||
Gfx::PGraphics graphics;
|
||||
Gfx::PViewport viewport;
|
||||
PScene scene;
|
||||
|
||||
@@ -86,6 +86,7 @@ SkyboxRenderPass::~SkyboxRenderPass()
|
||||
|
||||
void SkyboxRenderPass::beginFrame(const Component::Camera& cam)
|
||||
{
|
||||
RenderPass::beginFrame(cam);
|
||||
DataSource uniformUpdate;
|
||||
|
||||
viewParams.viewMatrix = cam.getViewMatrix();
|
||||
@@ -131,7 +132,7 @@ void SkyboxRenderPass::publishOutputs()
|
||||
.size = sizeof(ViewParameter),
|
||||
.data = nullptr,
|
||||
},
|
||||
.bDynamic = true
|
||||
.dynamic = true
|
||||
};
|
||||
viewParamsBuffer = graphics->createUniformBuffer(viewCreateInfo);
|
||||
|
||||
@@ -161,8 +162,8 @@ void SkyboxRenderPass::createRenderPass()
|
||||
baseColorAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD;
|
||||
Gfx::PRenderTargetAttachment depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
|
||||
depthAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD;
|
||||
Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(baseColorAttachment, depthAttachment);
|
||||
renderPass = graphics->createRenderPass(layout, viewport);
|
||||
Gfx::ORenderTargetLayout layout = new Gfx::RenderTargetLayout(baseColorAttachment, depthAttachment);
|
||||
renderPass = graphics->createRenderPass(std::move(layout), viewport);
|
||||
|
||||
ShaderCreateInfo createInfo;
|
||||
createInfo.name = "SkyboxVertex";
|
||||
|
||||
@@ -12,6 +12,8 @@ class SkyboxRenderPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
SkyboxRenderPass(Gfx::PGraphics graphics, PScene scene);
|
||||
SkyboxRenderPass(SkyboxRenderPass&&) = default;
|
||||
SkyboxRenderPass& operator=(SkyboxRenderPass&&) = default;
|
||||
virtual ~SkyboxRenderPass();
|
||||
virtual void beginFrame(const Component::Camera& cam) override;
|
||||
virtual void render() override;
|
||||
@@ -19,13 +21,13 @@ public:
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
private:
|
||||
Gfx::PVertexBuffer cubeBuffer;
|
||||
Gfx::PUniformBuffer viewParamsBuffer;
|
||||
Gfx::PDescriptorLayout descriptorLayout;
|
||||
Gfx::OVertexBuffer cubeBuffer;
|
||||
Gfx::OUniformBuffer viewParamsBuffer;
|
||||
Gfx::ODescriptorLayout descriptorLayout;
|
||||
Gfx::PDescriptorSet descriptorSet;
|
||||
Gfx::PPipelineLayout pipelineLayout;
|
||||
Gfx::PGraphicsPipeline pipeline;
|
||||
Gfx::PSamplerState skyboxSampler;
|
||||
Gfx::OPipelineLayout pipelineLayout;
|
||||
Gfx::OGraphicsPipeline pipeline;
|
||||
Gfx::OSamplerState skyboxSampler;
|
||||
Component::Skybox skybox;
|
||||
};
|
||||
DEFINE_REF(SkyboxRenderPass)
|
||||
|
||||
@@ -15,8 +15,9 @@ TextPass::~TextPass()
|
||||
|
||||
}
|
||||
|
||||
void TextPass::beginFrame(const Component::Camera&)
|
||||
void TextPass::beginFrame(const Component::Camera& cam)
|
||||
{
|
||||
RenderPass::beginFrame(cam);
|
||||
for(TextRender& render : texts)
|
||||
{
|
||||
FontData& fd = getFontData(render.font);
|
||||
@@ -126,7 +127,7 @@ void TextPass::createRenderPass()
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT,
|
||||
.attributeIndex = 0,
|
||||
.stride = sizeof(GlyphInstanceData),
|
||||
.bInstanced = 1
|
||||
.instanced = 1
|
||||
});
|
||||
elements.add({
|
||||
.binding = 0,
|
||||
@@ -134,7 +135,7 @@ void TextPass::createRenderPass()
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT,
|
||||
.attributeIndex = 1,
|
||||
.stride = sizeof(GlyphInstanceData),
|
||||
.bInstanced = 1
|
||||
.instanced = 1
|
||||
});
|
||||
elements.add({
|
||||
.binding = 0,
|
||||
@@ -142,7 +143,7 @@ void TextPass::createRenderPass()
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32_UINT,
|
||||
.attributeIndex = 2,
|
||||
.stride = sizeof(GlyphInstanceData),
|
||||
.bInstanced = 1
|
||||
.instanced = 1
|
||||
});
|
||||
declaration = graphics->createVertexDeclaration(elements);
|
||||
|
||||
@@ -160,7 +161,7 @@ void TextPass::createRenderPass()
|
||||
.size = sizeof(Matrix4),
|
||||
.data = nullptr,
|
||||
},
|
||||
.bDynamic = true,
|
||||
.dynamic = true,
|
||||
});
|
||||
|
||||
glyphSampler = graphics->createSamplerState({
|
||||
@@ -184,8 +185,8 @@ void TextPass::createRenderPass()
|
||||
.size = sizeof(TextData)});
|
||||
pipelineLayout->create();
|
||||
|
||||
Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(renderTarget, depthAttachment);
|
||||
renderPass = graphics->createRenderPass(layout, viewport);
|
||||
Gfx::ORenderTargetLayout layout = new Gfx::RenderTargetLayout(renderTarget, depthAttachment);
|
||||
renderPass = graphics->createRenderPass(std::move(layout), viewport);
|
||||
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.vertexDeclaration = declaration;
|
||||
@@ -229,6 +230,7 @@ TextPass::FontData& TextPass::getFontData(PFontAsset font)
|
||||
}
|
||||
fd.glyphDataSet = glyphData;
|
||||
|
||||
textureArrayLayout->reset();
|
||||
fd.textureArraySet = textureArrayLayout->allocateDescriptorSet();
|
||||
fd.textureArraySet->updateTextureArray(0, textures);
|
||||
fd.textureArraySet->writeChanges();
|
||||
|
||||
@@ -21,6 +21,8 @@ class TextPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
TextPass(Gfx::PGraphics graphics, PScene scene);
|
||||
TextPass(TextPass&&) = default;
|
||||
TextPass& operator=(TextPass&&) = default;
|
||||
virtual ~TextPass();
|
||||
virtual void beginFrame(const Component::Camera& cam) override;
|
||||
virtual void render() override;
|
||||
@@ -65,19 +67,19 @@ private:
|
||||
Gfx::PRenderTargetAttachment renderTarget;
|
||||
Gfx::PRenderTargetAttachment depthAttachment;
|
||||
|
||||
Gfx::PDescriptorLayout generalLayout;
|
||||
Gfx::PDescriptorLayout textureArrayLayout;
|
||||
Gfx::ODescriptorLayout generalLayout;
|
||||
Gfx::ODescriptorLayout textureArrayLayout;
|
||||
|
||||
Gfx::PDescriptorSet generalSet;
|
||||
|
||||
Gfx::PUniformBuffer projectionBuffer;
|
||||
Gfx::PSamplerState glyphSampler;
|
||||
Gfx::OUniformBuffer projectionBuffer;
|
||||
Gfx::OSamplerState glyphSampler;
|
||||
|
||||
Gfx::PVertexDeclaration declaration;
|
||||
Gfx::PVertexShader vertexShader;
|
||||
Gfx::PFragmentShader fragmentShader;
|
||||
Gfx::PPipelineLayout pipelineLayout;
|
||||
Gfx::PGraphicsPipeline pipeline;
|
||||
Gfx::OVertexDeclaration declaration;
|
||||
Gfx::OVertexShader vertexShader;
|
||||
Gfx::OFragmentShader fragmentShader;
|
||||
Gfx::OPipelineLayout pipelineLayout;
|
||||
Gfx::OGraphicsPipeline pipeline;
|
||||
Array<TextRender> texts;
|
||||
};
|
||||
DEFINE_REF(TextPass);
|
||||
|
||||
@@ -15,8 +15,9 @@ UIPass::~UIPass()
|
||||
|
||||
}
|
||||
|
||||
void UIPass::beginFrame(const Component::Camera&)
|
||||
void UIPass::beginFrame(const Component::Camera& cam)
|
||||
{
|
||||
RenderPass::beginFrame(cam);
|
||||
VertexBufferCreateInfo info = {
|
||||
.sourceData = {
|
||||
.size = (uint32)(sizeof(UI::RenderElementStyle) * renderElements.size()),
|
||||
@@ -103,7 +104,7 @@ void UIPass::createRenderPass()
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
|
||||
.attributeIndex = 0,
|
||||
.stride = sizeof(UI::RenderElementStyle),
|
||||
.bInstanced = 1
|
||||
.instanced = 1
|
||||
});
|
||||
decl.add({
|
||||
.binding = 0,
|
||||
@@ -111,7 +112,7 @@ void UIPass::createRenderPass()
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32_UINT,
|
||||
.attributeIndex = 1,
|
||||
.stride = sizeof(UI::RenderElementStyle),
|
||||
.bInstanced = 1
|
||||
.instanced = 1
|
||||
});
|
||||
decl.add({
|
||||
.binding = 0,
|
||||
@@ -119,7 +120,7 @@ void UIPass::createRenderPass()
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
|
||||
.attributeIndex = 2,
|
||||
.stride = sizeof(UI::RenderElementStyle),
|
||||
.bInstanced = 1
|
||||
.instanced = 1
|
||||
});
|
||||
decl.add({
|
||||
.binding = 0,
|
||||
@@ -127,7 +128,7 @@ void UIPass::createRenderPass()
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32_SFLOAT,
|
||||
.attributeIndex = 3,
|
||||
.stride = sizeof(UI::RenderElementStyle),
|
||||
.bInstanced = 1
|
||||
.instanced = 1
|
||||
});
|
||||
decl.add({
|
||||
.binding = 0,
|
||||
@@ -135,7 +136,7 @@ void UIPass::createRenderPass()
|
||||
.vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT,
|
||||
.attributeIndex = 4,
|
||||
.stride = sizeof(UI::RenderElementStyle),
|
||||
.bInstanced = 1
|
||||
.instanced = 1
|
||||
});
|
||||
declaration = graphics->createVertexDeclaration(decl);
|
||||
|
||||
@@ -152,7 +153,7 @@ void UIPass::createRenderPass()
|
||||
.size = sizeof(Matrix4),
|
||||
.data = (uint8*)&projectionMatrix,
|
||||
},
|
||||
.bDynamic = false,
|
||||
.dynamic = false,
|
||||
};
|
||||
Gfx::PUniformBuffer uniformBuffer = graphics->createUniformBuffer(info);
|
||||
Gfx::PSamplerState backgroundSampler = graphics->createSamplerState({});
|
||||
@@ -162,7 +163,7 @@ void UIPass::createRenderPass()
|
||||
.size = sizeof(uint32),
|
||||
.data = nullptr
|
||||
},
|
||||
.bDynamic = true,
|
||||
.dynamic = true,
|
||||
};
|
||||
|
||||
numTexturesBuffer = graphics->createUniformBuffer(info);
|
||||
@@ -176,8 +177,8 @@ void UIPass::createRenderPass()
|
||||
pipelineLayout->addDescriptorLayout(0, descriptorLayout);
|
||||
pipelineLayout->create();
|
||||
|
||||
Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(renderTarget, depthAttachment);
|
||||
renderPass = graphics->createRenderPass(layout, viewport);
|
||||
Gfx::ORenderTargetLayout layout = new Gfx::RenderTargetLayout(std::move(renderTarget), std::move(depthAttachment));
|
||||
renderPass = graphics->createRenderPass(std::move(layout), viewport);
|
||||
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.vertexDeclaration = declaration;
|
||||
|
||||
@@ -11,6 +11,8 @@ class UIPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
UIPass(Gfx::PGraphics graphics, PScene scene);
|
||||
UIPass(UIPass&&) = default;
|
||||
UIPass& operator=(UIPass&&) = default;
|
||||
virtual ~UIPass();
|
||||
virtual void beginFrame(const Component::Camera& cam) override;
|
||||
virtual void render() override;
|
||||
@@ -24,7 +26,7 @@ private:
|
||||
Gfx::OTexture2D depthBuffer;
|
||||
|
||||
Gfx::ODescriptorLayout descriptorLayout;
|
||||
Gfx::ODescriptorSet descriptorSet;
|
||||
Gfx::PDescriptorSet descriptorSet;
|
||||
|
||||
Gfx::OUniformBuffer numTexturesBuffer;
|
||||
Gfx::OVertexBuffer elementBuffer;
|
||||
|
||||
@@ -8,38 +8,40 @@ RenderTargetLayout::RenderTargetLayout()
|
||||
: inputAttachments()
|
||||
, colorAttachments()
|
||||
, depthAttachment()
|
||||
, width(0)
|
||||
, height(0)
|
||||
{
|
||||
}
|
||||
|
||||
RenderTargetLayout::RenderTargetLayout(ORenderTargetAttachment depthAttachment)
|
||||
RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment depthAttachment)
|
||||
: inputAttachments()
|
||||
, colorAttachments()
|
||||
, depthAttachment(std::move(depthAttachment))
|
||||
, depthAttachment(depthAttachment)
|
||||
, width(depthAttachment->getTexture()->getSizeX())
|
||||
, height(depthAttachment->getTexture()->getSizeY())
|
||||
{
|
||||
}
|
||||
|
||||
RenderTargetLayout::RenderTargetLayout(ORenderTargetAttachment colorAttachment, ORenderTargetAttachment depthAttachment)
|
||||
RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment colorAttachment, PRenderTargetAttachment depthAttachment)
|
||||
: inputAttachments()
|
||||
, depthAttachment(std::move(depthAttachment))
|
||||
, depthAttachment(depthAttachment)
|
||||
, width(depthAttachment->getTexture()->getSizeX())
|
||||
, height(depthAttachment->getTexture()->getSizeY())
|
||||
{
|
||||
colorAttachments.add(colorAttachment);
|
||||
}
|
||||
RenderTargetLayout::RenderTargetLayout(Array<ORenderTargetAttachment> colorAttachments, ORenderTargetAttachment depthAttachment)
|
||||
RenderTargetLayout::RenderTargetLayout(Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachment)
|
||||
: inputAttachments()
|
||||
, colorAttachments(std::move(colorAttachments))
|
||||
, depthAttachment(std::move(depthAttachment))
|
||||
, colorAttachments(colorAttachments)
|
||||
, depthAttachment(depthAttachment)
|
||||
, width(depthAttachment->getTexture()->getSizeX())
|
||||
, height(depthAttachment->getTexture()->getSizeY())
|
||||
{
|
||||
}
|
||||
RenderTargetLayout::RenderTargetLayout(Array<ORenderTargetAttachment> inputAttachments, Array<ORenderTargetAttachment> colorAttachments, ORenderTargetAttachment depthAttachment)
|
||||
: inputAttachments(std::move(inputAttachments))
|
||||
, colorAttachments(std::move(colorAttachments))
|
||||
, depthAttachment(std::move(depthAttachment))
|
||||
RenderTargetLayout::RenderTargetLayout(Array<PRenderTargetAttachment> inputAttachments, Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachment)
|
||||
: inputAttachments(inputAttachments)
|
||||
, colorAttachments(colorAttachments)
|
||||
, depthAttachment(depthAttachment)
|
||||
, width(depthAttachment->getTexture()->getSizeX())
|
||||
, height(depthAttachment->getTexture()->getSizeY())
|
||||
{
|
||||
|
||||
@@ -167,13 +167,13 @@ class RenderTargetLayout
|
||||
{
|
||||
public:
|
||||
RenderTargetLayout();
|
||||
RenderTargetLayout(ORenderTargetAttachment depthAttachment);
|
||||
RenderTargetLayout(ORenderTargetAttachment colorAttachment, ORenderTargetAttachment depthAttachment);
|
||||
RenderTargetLayout(Array<ORenderTargetAttachment> colorAttachments, ORenderTargetAttachment depthAttachmet);
|
||||
RenderTargetLayout(Array<ORenderTargetAttachment> inputAttachments, Array<ORenderTargetAttachment> colorAttachments, ORenderTargetAttachment depthAttachment);
|
||||
Array<ORenderTargetAttachment> inputAttachments;
|
||||
Array<ORenderTargetAttachment> colorAttachments;
|
||||
ORenderTargetAttachment depthAttachment;
|
||||
RenderTargetLayout(PRenderTargetAttachment depthAttachment);
|
||||
RenderTargetLayout(PRenderTargetAttachment colorAttachment, PRenderTargetAttachment depthAttachment);
|
||||
RenderTargetLayout(Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachmet);
|
||||
RenderTargetLayout(Array<PRenderTargetAttachment> inputAttachments, Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachment);
|
||||
Array<PRenderTargetAttachment> inputAttachments;
|
||||
Array<PRenderTargetAttachment> colorAttachments;
|
||||
PRenderTargetAttachment depthAttachment;
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
};
|
||||
@@ -184,7 +184,9 @@ class RenderPass
|
||||
public:
|
||||
RenderPass(ORenderTargetLayout layout) : layout(std::move(layout)) {}
|
||||
virtual ~RenderPass() {}
|
||||
inline PRenderTargetLayout getLayout() { return layout; }
|
||||
RenderPass(RenderPass&&) = default;
|
||||
RenderPass& operator=(RenderPass&&) = default;
|
||||
PRenderTargetLayout getLayout() const { return layout; }
|
||||
|
||||
protected:
|
||||
ORenderTargetLayout layout;
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#include "GraphicsResources.h"
|
||||
#include "Resources.h"
|
||||
#include "Graphics.h"
|
||||
#include "RenderPass/DepthPrepass.h"
|
||||
#include "RenderPass/BasePass.h"
|
||||
#include "Material/Material.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
QueueOwnedResource::QueueOwnedResource(QueueFamilyMapping mapping, QueueType startQueueType)
|
||||
: currentOwner(startQueueType)
|
||||
, mapping(mapping)
|
||||
|
||||
@@ -83,7 +83,7 @@ class VertexDeclaration
|
||||
{
|
||||
public:
|
||||
VertexDeclaration();
|
||||
~VertexDeclaration();
|
||||
virtual ~VertexDeclaration();
|
||||
|
||||
static PVertexDeclaration createDeclaration(PGraphics graphics, const Array<VertexElement>& elementList);
|
||||
private:
|
||||
@@ -126,7 +126,7 @@ public:
|
||||
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0;
|
||||
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0;
|
||||
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) = 0;
|
||||
virtual void dispatch(uint32 groupX, uint32 groupY, uint32 groupZ);
|
||||
virtual void dispatch(uint32 groupX, uint32 groupY, uint32 groupZ) = 0;
|
||||
std::string name;
|
||||
};
|
||||
DEFINE_REF(RenderCommand)
|
||||
|
||||
@@ -5,89 +5,125 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
std::string getShaderNameFromRenderPassType(Gfx::RenderPassType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Gfx::RenderPassType::DepthPrepass:
|
||||
return "DepthPrepass";
|
||||
case Gfx::RenderPassType::BasePass:
|
||||
return "ForwardPlus";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
void modifyRenderPassMacros(Gfx::RenderPassType type, Map<const char*, const char*>& defines)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Gfx::RenderPassType::DepthPrepass:
|
||||
DepthPrepass::modifyRenderPassMacros(defines);
|
||||
break;
|
||||
case Gfx::RenderPassType::BasePass:
|
||||
BasePass::modifyRenderPassMacros(defines);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ShaderMap::ShaderMap()
|
||||
ShaderCompiler::ShaderCompiler(Gfx::PGraphics graphics)
|
||||
: graphics(graphics)
|
||||
{
|
||||
}
|
||||
|
||||
ShaderMap::~ShaderMap()
|
||||
ShaderCompiler::~ShaderCompiler()
|
||||
{
|
||||
}
|
||||
|
||||
const ShaderCollection* ShaderMap::findShaders(PermutationId&& id) const
|
||||
const ShaderCollection* ShaderCompiler::findShaders(PermutationId id) const
|
||||
{
|
||||
for (uint32 i = 0; i < shaders.size(); ++i)
|
||||
return &shaders[id];
|
||||
}
|
||||
|
||||
void ShaderCompiler::registerMaterial(PMaterial material)
|
||||
{
|
||||
materials[material->getName()] = material;
|
||||
compile();
|
||||
}
|
||||
|
||||
void ShaderCompiler::registerVertexData(VertexData* vd)
|
||||
{
|
||||
vertexData[vd->getTypeName()] = vd;
|
||||
compile();
|
||||
}
|
||||
|
||||
void ShaderCompiler::registerRenderPass(std::string name, std::string mainFile, bool useMaterials, bool hasFragmentShader, std::string fragmentFile, bool useMeshShading, bool hasTaskShader, std::string taskFile)
|
||||
{
|
||||
passes[name] = PassConfig{
|
||||
.taskFile = taskFile,
|
||||
.mainFile = mainFile,
|
||||
.fragmentFile = fragmentFile,
|
||||
.hasFragmentShader = hasFragmentShader,
|
||||
.useMeshShading = useMeshShading,
|
||||
.hasTaskShader = hasTaskShader,
|
||||
.useMaterial = useMaterials,
|
||||
};
|
||||
compile();
|
||||
}
|
||||
|
||||
|
||||
void ShaderCompiler::compile()
|
||||
{
|
||||
ShaderPermutation permutation;
|
||||
for (const auto& [name, pass] : passes)
|
||||
{
|
||||
if (shaders[i].id == id)
|
||||
std::memset(&permutation, 0, sizeof(ShaderPermutation));
|
||||
permutation = {
|
||||
.hasFragment = pass.hasFragmentShader,
|
||||
.useMeshShading = pass.useMeshShading,
|
||||
.hasTaskShader = pass.hasTaskShader,
|
||||
};
|
||||
std::memcpy(permutation.vertexMeshFile, pass.mainFile.c_str(), sizeof(permutation.vertexMeshFile));
|
||||
if (pass.hasFragmentShader)
|
||||
{
|
||||
return &(shaders[i]);
|
||||
std::memcpy(permutation.fragmentFile, pass.fragmentFile.c_str(), sizeof(permutation.fragmentFile));
|
||||
}
|
||||
if (pass.hasTaskShader)
|
||||
{
|
||||
std::memcpy(permutation.taskFile, pass.taskFile.c_str(), sizeof(permutation.taskFile));
|
||||
}
|
||||
for (const auto& [vdName, vd] : vertexData)
|
||||
{
|
||||
std::memcpy(permutation.vertexDataName, vd->getTypeName().c_str(), sizeof(permutation.vertexDataName));
|
||||
if (pass.useMaterial)
|
||||
{
|
||||
for (const auto& [matName, mat] : materials)
|
||||
{
|
||||
std::memcpy(permutation.materialName, matName.c_str(), sizeof(permutation.materialName));
|
||||
createShaders(permutation);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::memset(permutation.materialName, 0, sizeof(permutation.materialName));
|
||||
createShaders(permutation);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
ShaderCollection& ShaderMap::createShaders(
|
||||
PGraphics graphics,
|
||||
RenderPassType renderPass,
|
||||
PMaterial material,
|
||||
bool /*bPositionOnly*/)
|
||||
|
||||
ShaderCollection& ShaderCompiler::createShaders(ShaderPermutation permutation)
|
||||
{
|
||||
std::scoped_lock lock(shadersLock);
|
||||
ShaderCollection& collection = shaders.add();
|
||||
//collection.vertexDeclaration = bPositionOnly ? vertexInput->getPositionDeclaration() : vertexInput->getDeclaration();
|
||||
ShaderCollection collection;
|
||||
|
||||
ShaderCreateInfo createInfo;
|
||||
createInfo.entryPoint = "vertexMain";
|
||||
createInfo.typeParameter = { material->getName().c_str() };
|
||||
createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "1";
|
||||
createInfo.defines["USE_INSTANCING"] = "0";
|
||||
modifyRenderPassMacros(renderPass, createInfo.defines);
|
||||
createInfo.name = getShaderNameFromRenderPassType(renderPass) + " Material " + material->getName();
|
||||
createInfo.typeParameter = { permutation.materialName, permutation.vertexDataName };
|
||||
createInfo.name = std::format("Material {0}", permutation.materialName);
|
||||
createInfo.additionalModules.add(permutation.materialName);
|
||||
createInfo.additionalModules.add(permutation.vertexDataName);
|
||||
|
||||
std::ifstream codeStream("./shaders/" + getShaderNameFromRenderPassType(renderPass));
|
||||
|
||||
createInfo.mainModule = getShaderNameFromRenderPassType(renderPass);
|
||||
createInfo.additionalModules.add(vertexInput->getShaderFilename());
|
||||
createInfo.additionalModules.add(material->getName());
|
||||
|
||||
collection.vertexShader = graphics->createVertexShader(createInfo);
|
||||
|
||||
if (renderPass != RenderPassType::DepthPrepass)
|
||||
if (permutation.useMeshShading)
|
||||
{
|
||||
createInfo.entryPoint = "fragmentMain";
|
||||
if (permutation.hasTaskShader)
|
||||
{
|
||||
createInfo.mainModule = permutation.taskFile;
|
||||
createInfo.entryPoint = "taskMain";
|
||||
collection.taskShader = graphics->createTaskShader(createInfo);
|
||||
}
|
||||
createInfo.mainModule = permutation.vertexMeshFile;
|
||||
createInfo.entryPoint = "meshMain";
|
||||
collection.meshShader = graphics->createMeshShader(createInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
createInfo.mainModule = permutation.vertexMeshFile;
|
||||
createInfo.entryPoint = "vertexMain";
|
||||
collection.vertexShader = graphics->createVertexShader(createInfo);
|
||||
}
|
||||
|
||||
if (permutation.hasFragment)
|
||||
{
|
||||
createInfo.mainModule = permutation.fragmentFile;
|
||||
createInfo.entryPoint = "fragmentMain";
|
||||
collection.fragmentShader = graphics->createFragmentShader(createInfo);
|
||||
}
|
||||
ShaderPermutation permutation;
|
||||
std::string materialName = material->getName();
|
||||
std::string vertexInputName = vertexInput->getName();
|
||||
permutation.passType = renderPass;
|
||||
std::memcpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName));
|
||||
std::memcpy(permutation.vertexInputName, vertexInputName.c_str(), sizeof(permutation.vertexInputName));
|
||||
collection.id = PermutationId(permutation);
|
||||
PermutationId perm = PermutationId(permutation);
|
||||
shaders[perm] = std::move(collection);
|
||||
|
||||
return collection;
|
||||
return shaders[perm];
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "Enums.h"
|
||||
#include "CRC.h"
|
||||
#include "Resources.h"
|
||||
#include "VertexData.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -52,9 +53,14 @@ DEFINE_REF(ComputeShader)
|
||||
//using the type parameters used to generate it
|
||||
struct ShaderPermutation
|
||||
{
|
||||
RenderPassType passType;
|
||||
char vertexInputName[15];
|
||||
char materialName[16];
|
||||
char taskFile[32];
|
||||
char vertexMeshFile[32];
|
||||
char fragmentFile[32];
|
||||
char vertexDataName[32];
|
||||
char materialName[32];
|
||||
uint8 hasFragment : 1;
|
||||
uint8 useMeshShading : 1;
|
||||
uint8 hasTaskShader : 1;
|
||||
//TODO: lightmapping etc
|
||||
};
|
||||
//Hashed ShaderPermutation for fast lookup
|
||||
@@ -67,47 +73,59 @@ struct PermutationId
|
||||
PermutationId(ShaderPermutation permutation)
|
||||
: hash(CRC::Calculate(&permutation, sizeof(ShaderPermutation), CRC::CRC_32()))
|
||||
{}
|
||||
friend inline bool operator==(const PermutationId& lhs, const PermutationId& rhs)
|
||||
friend constexpr bool operator==(const PermutationId& lhs, const PermutationId& rhs)
|
||||
{
|
||||
return lhs.hash == rhs.hash;
|
||||
}
|
||||
friend inline bool operator!=(const PermutationId& lhs, const PermutationId& rhs)
|
||||
friend constexpr auto operator<=>(const PermutationId& lhs, const PermutationId& rhs)
|
||||
{
|
||||
return lhs.hash != rhs.hash;
|
||||
}
|
||||
friend inline bool operator<(const PermutationId& lhs, const PermutationId& rhs)
|
||||
{
|
||||
return lhs.hash < rhs.hash;
|
||||
}
|
||||
friend inline bool operator>(const PermutationId& lhs, const PermutationId& rhs)
|
||||
{
|
||||
return lhs.hash > rhs.hash;
|
||||
return lhs.hash <=> rhs.hash;
|
||||
}
|
||||
};
|
||||
struct ShaderCollection
|
||||
{
|
||||
PermutationId id;
|
||||
|
||||
OVertexDeclaration vertexDeclaration;
|
||||
OVertexShader vertexShader;
|
||||
OTaskShader taskShader;
|
||||
OMeshShader meshShader;
|
||||
OFragmentShader fragmentShader;
|
||||
};
|
||||
class ShaderMap
|
||||
class ShaderCompiler
|
||||
{
|
||||
public:
|
||||
ShaderMap();
|
||||
~ShaderMap();
|
||||
const ShaderCollection* findShaders(PermutationId&& id) const;
|
||||
ShaderCollection& createShaders(
|
||||
PGraphics graphics,
|
||||
RenderPassType passName,
|
||||
bool bPositionOnly);
|
||||
ShaderCompiler(Gfx::PGraphics graphics);
|
||||
~ShaderCompiler();
|
||||
const ShaderCollection* findShaders(PermutationId id) const;
|
||||
void registerMaterial(PMaterial material);
|
||||
void registerVertexData(VertexData* vertexData);
|
||||
void registerRenderPass(std::string name,
|
||||
std::string mainFile,
|
||||
bool useMaterials = false,
|
||||
bool hasFragmentShader = false,
|
||||
std::string fragmentFile = "",
|
||||
bool useMeshShading = false,
|
||||
bool hasTaskShader = false,
|
||||
std::string taskFile = "");
|
||||
private:
|
||||
void compile();
|
||||
ShaderCollection& createShaders(ShaderPermutation permutation);
|
||||
std::mutex shadersLock;
|
||||
Array<ShaderCollection> shaders;
|
||||
Map<PermutationId, ShaderCollection> shaders;
|
||||
Map<std::string, PMaterial> materials;
|
||||
Map<std::string, VertexData*> vertexData;
|
||||
struct PassConfig
|
||||
{
|
||||
std::string taskFile;
|
||||
std::string mainFile;
|
||||
std::string fragmentFile;
|
||||
bool hasFragmentShader;
|
||||
bool useMeshShading;
|
||||
bool hasTaskShader;
|
||||
bool useMaterial;
|
||||
};
|
||||
Map<std::string, PassConfig> passes;
|
||||
Gfx::PGraphics graphics;
|
||||
};
|
||||
DEFINE_REF(ShaderMap)
|
||||
DEFINE_REF(ShaderCompiler)
|
||||
}
|
||||
} // namespace Seele
|
||||
@@ -1,18 +0,0 @@
|
||||
#include "ShaderCompiler.h"
|
||||
#include "Graphics.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
ShaderCompiler::ShaderCompiler(PGraphics graphics)
|
||||
: graphics(graphics)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ShaderCompiler::~ShaderCompiler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
#include "Material/Material.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_NAME_REF(Gfx, Graphics)
|
||||
namespace Gfx
|
||||
{
|
||||
class ShaderCompiler
|
||||
{
|
||||
public:
|
||||
ShaderCompiler(PGraphics graphics);
|
||||
~ShaderCompiler();
|
||||
private:
|
||||
PGraphics graphics;
|
||||
};
|
||||
DEFINE_REF(ShaderCompiler)
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
@@ -135,7 +135,7 @@ void StaticMeshVertexData::resizeBuffers()
|
||||
.size = verticesAllocated * sizeof(Vector),
|
||||
},
|
||||
.stride = sizeof(Vector),
|
||||
.bDynamic = true,
|
||||
.dynamic = true,
|
||||
};
|
||||
positions = graphics->createShaderBuffer(createInfo);
|
||||
normals = graphics->createShaderBuffer(createInfo);
|
||||
@@ -174,6 +174,7 @@ void StaticMeshVertexData::updateBuffers()
|
||||
.size = biTangentData.size() * sizeof(Vector),
|
||||
.data = (uint8*)biTangentData.data(),
|
||||
});
|
||||
descriptorLayout->reset();
|
||||
descriptorSet = descriptorLayout->allocateDescriptorSet();
|
||||
descriptorSet->updateBuffer(0, positions);
|
||||
descriptorSet->updateBuffer(1, texCoords);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "Math/Vector.h"
|
||||
#include "VertexData.h"
|
||||
|
||||
namespace Seele
|
||||
@@ -35,6 +36,6 @@ private:
|
||||
Gfx::OShaderBuffer biTangents;
|
||||
Array<Vector> biTangentData;
|
||||
Gfx::ODescriptorLayout descriptorLayout;
|
||||
Gfx::ODescriptorSet descriptorSet;
|
||||
Gfx::PDescriptorSet descriptorSet;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ void VertexData::loadMesh(MeshId id, Array<Meshlet> loadedMeshlets)
|
||||
.data = (uint8*)meshlets.data()
|
||||
},
|
||||
.stride = sizeof(MeshletDescription),
|
||||
.bDynamic = true,
|
||||
.dynamic = true,
|
||||
});
|
||||
vertexIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo {
|
||||
.sourceData = {
|
||||
@@ -78,7 +78,7 @@ void VertexData::loadMesh(MeshId id, Array<Meshlet> loadedMeshlets)
|
||||
.data = (uint8*)vertexIndices.data(),
|
||||
},
|
||||
.stride = sizeof(uint32),
|
||||
.bDynamic = true,
|
||||
.dynamic = true,
|
||||
});
|
||||
primitiveIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo {
|
||||
.sourceData = {
|
||||
@@ -86,7 +86,7 @@ void VertexData::loadMesh(MeshId id, Array<Meshlet> loadedMeshlets)
|
||||
.data = (uint8*)primitiveIndices.data(),
|
||||
},
|
||||
.stride = sizeof(uint8),
|
||||
.bDynamic = true,
|
||||
.dynamic = true,
|
||||
});
|
||||
|
||||
}
|
||||
@@ -114,6 +114,7 @@ void VertexData::createDescriptors()
|
||||
},
|
||||
.stride = sizeof(InstanceData)
|
||||
});
|
||||
instanceDataLayout->reset();
|
||||
matInst.descriptorSet = instanceDataLayout->allocateDescriptorSet();
|
||||
matInst.descriptorSet->updateBuffer(0, instanceBuffer);
|
||||
if (Gfx::useMeshShading)
|
||||
@@ -187,15 +188,18 @@ void Seele::VertexData::init(Gfx::PGraphics graphics)
|
||||
}
|
||||
instanceDataLayout->create();
|
||||
resizeBuffers();
|
||||
graphics->getShaderCompiler()->registerVertexData(this);
|
||||
}
|
||||
|
||||
VertexData::VertexData()
|
||||
: idCounter(0)
|
||||
, dirty(false)
|
||||
, head(0)
|
||||
, verticesAllocated(0)
|
||||
{
|
||||
}
|
||||
|
||||
void Meshlet::save(ArchiveBuffer& buffer)
|
||||
void Meshlet::save(ArchiveBuffer& buffer) const
|
||||
{
|
||||
Serialization::save(buffer, uniqueVertices);
|
||||
Serialization::save(buffer, primitiveLayout);
|
||||
|
||||
@@ -26,7 +26,7 @@ struct Meshlet
|
||||
StaticArray<uint8, Gfx::numPrimitivesPerMeshlet * 3> primitiveLayout; // indices into the uniqueVertices array, only uint8 needed
|
||||
uint32 numVertices;
|
||||
uint32 numPrimitives;
|
||||
void save(ArchiveBuffer& buffer);
|
||||
void save(ArchiveBuffer& buffer) const;
|
||||
void load(ArchiveBuffer& buffer);
|
||||
};
|
||||
class VertexData
|
||||
@@ -101,7 +101,7 @@ protected:
|
||||
Array<MeshletDescription> meshlets;
|
||||
Array<uint8> primitiveIndices;
|
||||
Array<uint32> vertexIndices;
|
||||
Gfx::OGraphics graphics;
|
||||
Gfx::PGraphics graphics;
|
||||
Gfx::ODescriptorLayout instanceDataLayout;
|
||||
// for mesh shading
|
||||
Gfx::OShaderBuffer meshletBuffer;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
SubAllocation::SubAllocation(Allocation *owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize)
|
||||
SubAllocation::SubAllocation(PAllocation owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize)
|
||||
: owner(owner)
|
||||
, size(size)
|
||||
, allocatedOffset(allocatedOffset)
|
||||
@@ -18,12 +18,22 @@ SubAllocation::~SubAllocation()
|
||||
owner->markFree(this);
|
||||
}
|
||||
|
||||
VkDeviceMemory SubAllocation::getHandle() const
|
||||
constexpr VkDeviceMemory SubAllocation::getHandle() const
|
||||
{
|
||||
return owner->getHandle();
|
||||
}
|
||||
|
||||
bool SubAllocation::isReadable() const
|
||||
constexpr VkDeviceSize SubAllocation::getSize() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
constexpr VkDeviceSize SubAllocation::getOffset() const
|
||||
{
|
||||
return alignedOffset;
|
||||
}
|
||||
|
||||
constexpr bool SubAllocation::isReadable() const
|
||||
{
|
||||
return owner->isReadable();
|
||||
}
|
||||
@@ -61,8 +71,7 @@ Allocation::Allocation(PGraphics graphics, PAllocator allocator, VkDeviceSize si
|
||||
allocInfo.pNext = dedicatedInfo;
|
||||
VK_CHECK(vkAllocateMemory(device, &allocInfo, nullptr, &allocatedMemory));
|
||||
bytesAllocated = size;
|
||||
PSubAllocation freeRange = new SubAllocation(this, 0, size, 0, size);
|
||||
freeRanges[0] = freeRange;
|
||||
freeRanges[0] = new SubAllocation(this, 0, size, 0, size);
|
||||
|
||||
canMap = (properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
|
||||
isMapped = false;
|
||||
@@ -72,15 +81,15 @@ Allocation::~Allocation()
|
||||
{
|
||||
}
|
||||
|
||||
PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDeviceSize alignment)
|
||||
OSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDeviceSize alignment)
|
||||
{
|
||||
std::scoped_lock lck(lock);
|
||||
if (isDedicated)
|
||||
{
|
||||
if (activeAllocations.empty() && requestedSize == bytesAllocated)
|
||||
{
|
||||
PSubAllocation suballoc = freeRanges[0];
|
||||
activeAllocations[0] = suballoc.getHandle();
|
||||
OSubAllocation suballoc = std::move(freeRanges[0]);
|
||||
activeAllocations.add(suballoc);
|
||||
freeRanges.clear();
|
||||
bytesUsed += requestedSize;
|
||||
return suballoc;
|
||||
@@ -92,37 +101,38 @@ PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice
|
||||
}
|
||||
for (auto& it : freeRanges)
|
||||
{
|
||||
VkDeviceSize allocatedOffset = it.first;
|
||||
PSubAllocation freeAllocation = it.second;
|
||||
VkDeviceSize allocatedOffset = it.key;
|
||||
OSubAllocation& freeAllocation = it.value;
|
||||
assert(allocatedOffset == freeAllocation->allocatedOffset);
|
||||
VkDeviceSize alignedOffset = align(allocatedOffset, alignment);
|
||||
VkDeviceSize alignmentAdjustment = alignedOffset - allocatedOffset;
|
||||
VkDeviceSize size = alignmentAdjustment + requestedSize;
|
||||
if (freeAllocation->size == size)
|
||||
VkDeviceSize alignedOffset = allocatedOffset + alignment - 1;
|
||||
alignedOffset /= alignment;
|
||||
alignedOffset *= alignment;
|
||||
VkDeviceSize allocatedSize = requestedSize + (alignedOffset - allocatedOffset);
|
||||
if (freeAllocation->size == allocatedSize)
|
||||
{
|
||||
activeAllocations[allocatedOffset] = freeAllocation.getHandle();
|
||||
activeAllocations.add(freeAllocation);
|
||||
freeRanges.erase(allocatedOffset);
|
||||
bytesUsed += size;
|
||||
return freeAllocation;
|
||||
bytesUsed += allocatedSize;
|
||||
return std::move(freeAllocation);
|
||||
}
|
||||
else if (size < freeAllocation->allocatedSize)
|
||||
else if (allocatedSize < freeAllocation->allocatedSize)
|
||||
{
|
||||
freeAllocation->size -= size;
|
||||
freeAllocation->allocatedSize -= size;
|
||||
freeAllocation->allocatedOffset += size;
|
||||
freeAllocation->alignedOffset += size;
|
||||
PSubAllocation subAlloc = new SubAllocation(this, allocatedOffset, size, alignedOffset, size);
|
||||
activeAllocations[allocatedOffset] = subAlloc.getHandle();
|
||||
freeAllocation->size -= allocatedSize;
|
||||
freeAllocation->allocatedSize -= allocatedSize;
|
||||
freeAllocation->allocatedOffset += allocatedSize;
|
||||
freeAllocation->alignedOffset += allocatedSize;
|
||||
OSubAllocation subAlloc = new SubAllocation(this, allocatedOffset, allocatedSize, alignedOffset, allocatedSize);
|
||||
activeAllocations.add(subAlloc);
|
||||
freeRanges[freeAllocation->allocatedOffset] = std::move(freeAllocation);
|
||||
freeRanges.erase(allocatedOffset);
|
||||
freeRanges[freeAllocation->allocatedOffset] = freeAllocation;
|
||||
bytesUsed += size;
|
||||
bytesUsed += allocatedSize;
|
||||
return subAlloc;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Allocation::markFree(SubAllocation *allocation)
|
||||
void Allocation::markFree(PSubAllocation allocation)
|
||||
{
|
||||
// Dont free if it is already a free allocation, since they also mark themselves on deletion
|
||||
if (freeRanges.find(allocation->allocatedOffset) != freeRanges.end())
|
||||
@@ -143,7 +153,7 @@ void Allocation::markFree(SubAllocation *allocation)
|
||||
&& freeAlloc->allocatedOffset + freeAlloc->allocatedSize >= upperBound)
|
||||
{
|
||||
// allocation is already in a free region
|
||||
return;
|
||||
assert(false);
|
||||
}
|
||||
if (freeAlloc->allocatedOffset + freeAlloc->allocatedSize == lowerBound)
|
||||
{
|
||||
@@ -157,35 +167,34 @@ void Allocation::markFree(SubAllocation *allocation)
|
||||
auto foundAlloc = freeRanges.find(upperBound);
|
||||
if (foundAlloc != freeRanges.end())
|
||||
{
|
||||
freeRangeToDelete = foundAlloc->second;
|
||||
// There is a free allocation ending where the new free one ends
|
||||
freeRangeToDelete = foundAlloc->value;
|
||||
if (allocHandle != nullptr)
|
||||
{
|
||||
// extend allocHandle by another foundAlloc->allocatedSize bytes
|
||||
allocHandle->allocatedSize += foundAlloc->second->allocatedSize;
|
||||
freeRanges.erase(foundAlloc->first);
|
||||
allocHandle->allocatedSize += foundAlloc->value->allocatedSize;
|
||||
freeRanges.erase(foundAlloc->key);
|
||||
}
|
||||
else
|
||||
{
|
||||
// set foundAlloc back by size amount
|
||||
allocHandle = foundAlloc->second;
|
||||
allocHandle = foundAlloc->value;
|
||||
allocHandle->allocatedOffset -= allocation->allocatedSize;
|
||||
allocHandle->alignedOffset -= allocation->allocatedSize;
|
||||
allocHandle->size += allocation->allocatedSize;
|
||||
allocHandle->allocatedSize += allocation->allocatedSize;
|
||||
// place back at correct offset
|
||||
freeRanges[allocHandle->allocatedOffset] = allocHandle;
|
||||
// place back at correct offset, move original owning pointer
|
||||
freeRanges[allocHandle->allocatedOffset] = std::move(foundAlloc->value);
|
||||
// remove from offset map since key changes
|
||||
freeRanges.erase(foundAlloc->first);
|
||||
freeRanges.erase(foundAlloc->key);
|
||||
}
|
||||
}
|
||||
|
||||
if (allocHandle == nullptr)
|
||||
{
|
||||
allocHandle = new SubAllocation(this, allocation->allocatedOffset, allocation->size, allocation->alignedOffset, allocation->allocatedSize);
|
||||
freeRanges[allocation->allocatedOffset] = allocHandle;
|
||||
freeRanges[allocation->allocatedOffset] = new SubAllocation(this, allocation->allocatedOffset, allocation->size, allocation->alignedOffset, allocation->allocatedSize);
|
||||
}
|
||||
activeAllocations.erase(allocation->allocatedOffset);
|
||||
activeAllocations.remove_if([&](const PSubAllocation& a) {return a.getHandle() == allocation.getHandle(); });
|
||||
}
|
||||
bytesUsed -= allocation->allocatedSize;
|
||||
if(bytesUsed == 0)
|
||||
@@ -194,25 +203,73 @@ void Allocation::markFree(SubAllocation *allocation)
|
||||
}
|
||||
}
|
||||
|
||||
constexpr VkDeviceMemory Allocation::getHandle() const
|
||||
{
|
||||
return allocatedMemory;
|
||||
}
|
||||
|
||||
constexpr void* Allocation::getMappedPointer()
|
||||
{
|
||||
if (!canMap)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (!isMapped)
|
||||
{
|
||||
vkMapMemory(device, allocatedMemory, 0, bytesAllocated, 0, &mappedPointer);
|
||||
isMapped = true;
|
||||
}
|
||||
return mappedPointer;
|
||||
}
|
||||
|
||||
constexpr bool Allocation::isReadable() const
|
||||
{
|
||||
return readable;
|
||||
}
|
||||
|
||||
void Allocation::flushMemory()
|
||||
{
|
||||
VkMappedMemoryRange range = {
|
||||
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
||||
.pNext = 0,
|
||||
.memory = allocatedMemory,
|
||||
.offset = 0,
|
||||
.size = bytesAllocated,
|
||||
};
|
||||
vkFlushMappedMemoryRanges(device, 1, &range);
|
||||
}
|
||||
|
||||
void Allocation::invalidateMemory()
|
||||
{
|
||||
VkMappedMemoryRange range = {
|
||||
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
||||
.pNext = 0,
|
||||
.memory = allocatedMemory,
|
||||
.size = bytesAllocated,
|
||||
};
|
||||
vkInvalidateMappedMemoryRanges(device, 1, &range);
|
||||
}
|
||||
|
||||
Allocator::Allocator(PGraphics graphics)
|
||||
: graphics(graphics)
|
||||
{
|
||||
vkGetPhysicalDeviceMemoryProperties(graphics->getPhysicalDevice(), &memProperties);
|
||||
heaps.resize(memProperties.memoryHeapCount);
|
||||
heaps.reserve(memProperties.memoryHeapCount);
|
||||
for (size_t i = 0; i < memProperties.memoryHeapCount; ++i)
|
||||
{
|
||||
VkMemoryHeap memoryHeap = memProperties.memoryHeaps[i];
|
||||
HeapInfo &heapInfo = heaps[i];
|
||||
HeapInfo heapInfo;
|
||||
heapInfo.maxSize = memoryHeap.size;
|
||||
heaps.add(std::move(heapInfo));
|
||||
}
|
||||
}
|
||||
|
||||
Allocator::~Allocator()
|
||||
{
|
||||
std::scoped_lock lck(lock);
|
||||
for (auto heap : heaps)
|
||||
for (auto& heap : heaps)
|
||||
{
|
||||
for (auto alloc : heap.allocations)
|
||||
for (auto& alloc : heap.allocations)
|
||||
{
|
||||
assert(alloc->activeAllocations.empty());
|
||||
assert(alloc->freeRanges.size() == 1);
|
||||
@@ -222,7 +279,7 @@ Allocator::~Allocator()
|
||||
graphics = nullptr;
|
||||
}
|
||||
|
||||
PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo)
|
||||
OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo)
|
||||
{
|
||||
std::scoped_lock lck(lock);
|
||||
const VkMemoryRequirements &requirements = memRequirements2.memoryRequirements;
|
||||
@@ -234,17 +291,17 @@ PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2
|
||||
VkMemoryDedicatedRequirements *dedicatedReq = (VkMemoryDedicatedRequirements *)memRequirements2.pNext;
|
||||
if (dedicatedReq->prefersDedicatedAllocation)
|
||||
{
|
||||
PAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo);
|
||||
heaps[heapIndex].allocations.add(newAllocation);
|
||||
OAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo);
|
||||
heaps[heapIndex].inUse += newAllocation->bytesAllocated;
|
||||
return newAllocation->getSuballocation(requirements.size, requirements.alignment);
|
||||
heaps[heapIndex].allocations.add(std::move(newAllocation));
|
||||
return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment);
|
||||
}
|
||||
}
|
||||
for (auto alloc : heaps[heapIndex].allocations)
|
||||
for (auto& alloc : heaps[heapIndex].allocations)
|
||||
{
|
||||
if(alloc->memoryTypeIndex == memoryTypeIndex)
|
||||
{
|
||||
PSubAllocation suballoc = alloc->getSuballocation(requirements.size, requirements.alignment);
|
||||
OSubAllocation suballoc = alloc->getSuballocation(requirements.size, requirements.alignment);
|
||||
if (suballoc != nullptr)
|
||||
{
|
||||
return suballoc;
|
||||
@@ -253,16 +310,16 @@ PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2
|
||||
}
|
||||
|
||||
// no suitable allocations found, allocate new block
|
||||
PAllocation newAllocation = new Allocation(graphics, this, (requirements.size > MemoryBlockSize) ? requirements.size : (VkDeviceSize)MemoryBlockSize, memoryTypeIndex, properties, nullptr);
|
||||
heaps[heapIndex].allocations.add(newAllocation);
|
||||
OAllocation newAllocation = new Allocation(graphics, this, (requirements.size > MemoryBlockSize) ? requirements.size : (VkDeviceSize)MemoryBlockSize, memoryTypeIndex, properties, nullptr);
|
||||
heaps[heapIndex].inUse += newAllocation->bytesAllocated;
|
||||
return newAllocation->getSuballocation(requirements.size, requirements.alignment);
|
||||
heaps[heapIndex].allocations.add(std::move(newAllocation));
|
||||
return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment);
|
||||
}
|
||||
|
||||
void Allocator::free(Allocation *allocation)
|
||||
{
|
||||
std::scoped_lock lck(lock);
|
||||
for (auto heap : heaps)
|
||||
for (auto& heap : heaps)
|
||||
{
|
||||
for (uint32 i = 0; i < heap.allocations.size(); ++i)
|
||||
{
|
||||
@@ -288,12 +345,58 @@ uint32 Allocator::findMemoryType(uint32 typeFilter, VkMemoryPropertyFlags proper
|
||||
throw std::runtime_error("error finding memory");
|
||||
}
|
||||
|
||||
StagingBuffer::StagingBuffer()
|
||||
StagingBuffer::StagingBuffer(OSubAllocation allocation, VkBuffer buffer, VkBufferUsageFlags usage, uint8 readable)
|
||||
: allocation(std::move(allocation))
|
||||
, buffer(buffer)
|
||||
, usage(usage)
|
||||
, readable(readable)
|
||||
{
|
||||
}
|
||||
|
||||
StagingBuffer::~StagingBuffer()
|
||||
{
|
||||
assert(allocation == nullptr);
|
||||
// buffer went out of scope without being cleaned up
|
||||
}
|
||||
|
||||
void* StagingBuffer::getMappedPointer()
|
||||
{
|
||||
return allocation->getMappedPointer();
|
||||
}
|
||||
|
||||
void StagingBuffer::flushMappedMemory()
|
||||
{
|
||||
allocation->flushMemory();
|
||||
}
|
||||
|
||||
void StagingBuffer::invalidateMemory()
|
||||
{
|
||||
allocation->invalidateMemory();
|
||||
}
|
||||
|
||||
constexpr VkDeviceMemory StagingBuffer::getMemoryHandle() const
|
||||
{
|
||||
return allocation->getHandle();
|
||||
}
|
||||
|
||||
constexpr VkDeviceSize StagingBuffer::getOffset() const
|
||||
{
|
||||
return allocation->getOffset();
|
||||
}
|
||||
|
||||
constexpr uint64 StagingBuffer::getSize() const
|
||||
{
|
||||
return allocation->getSize();
|
||||
}
|
||||
|
||||
constexpr bool StagingBuffer::isReadable() const
|
||||
{
|
||||
return readable;
|
||||
}
|
||||
|
||||
constexpr VkBufferUsageFlags StagingBuffer::getUsage() const
|
||||
{
|
||||
return usage;
|
||||
}
|
||||
|
||||
StagingManager::StagingManager(PGraphics graphics, PAllocator allocator)
|
||||
@@ -309,22 +412,22 @@ void StagingManager::clearPending()
|
||||
{
|
||||
}
|
||||
|
||||
PStagingBuffer StagingManager::allocateStagingBuffer(uint64 size, VkBufferUsageFlags usage, bool bCPURead)
|
||||
OStagingBuffer StagingManager::allocateStagingBuffer(uint64 size, VkBufferUsageFlags usage, bool readable)
|
||||
{
|
||||
std::scoped_lock l(lock);
|
||||
for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it)
|
||||
{
|
||||
auto freeBuffer = *it;
|
||||
if (freeBuffer->getSize() == size && freeBuffer->isReadable() == bCPURead && freeBuffer->usage == usage)
|
||||
auto& freeBuffer = *it;
|
||||
if (freeBuffer->getSize() == size && freeBuffer->isReadable() == readable && freeBuffer->getUsage() == usage)
|
||||
{
|
||||
//std::cout << "Reusing staging buffer" << std::endl;
|
||||
activeBuffers.add(freeBuffer.getHandle());
|
||||
activeBuffers.add(freeBuffer);
|
||||
freeBuffers.remove(it, false);
|
||||
return freeBuffer;
|
||||
return std::move(freeBuffer);
|
||||
}
|
||||
}
|
||||
//std::cout << "Creating new stagingbuffer" << std::endl;
|
||||
PStagingBuffer stagingBuffer = new StagingBuffer();
|
||||
VkBuffer buffer;
|
||||
VkBufferCreateInfo stagingBufferCreateInfo = init::BufferCreateInfo(usage, size);
|
||||
stagingBufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
uint32 queueIndex = graphics->getFamilyMapping().getQueueTypeFamilyIndex(Gfx::QueueType::DEDICATED_TRANSFER);
|
||||
@@ -332,37 +435,42 @@ PStagingBuffer StagingManager::allocateStagingBuffer(uint64 size, VkBufferUsageF
|
||||
stagingBufferCreateInfo.pQueueFamilyIndices = &queueIndex;
|
||||
VkDevice vulkanDevice = graphics->getDevice();
|
||||
|
||||
VK_CHECK(vkCreateBuffer(vulkanDevice, &stagingBufferCreateInfo, nullptr, &stagingBuffer->buffer));
|
||||
VK_CHECK(vkCreateBuffer(vulkanDevice, &stagingBufferCreateInfo, nullptr, &buffer));
|
||||
|
||||
VkMemoryDedicatedRequirements dedicatedReqs;
|
||||
dedicatedReqs.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
|
||||
dedicatedReqs.pNext = nullptr;
|
||||
VkMemoryRequirements2 memReqs;
|
||||
memReqs.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
|
||||
memReqs.pNext = &dedicatedReqs;
|
||||
VkBufferMemoryRequirementsInfo2 bufferQuery;
|
||||
bufferQuery.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2;
|
||||
bufferQuery.pNext = nullptr;
|
||||
bufferQuery.buffer = stagingBuffer->buffer;
|
||||
VkMemoryDedicatedRequirements dedicatedReqs = {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
|
||||
.pNext = nullptr,
|
||||
};
|
||||
VkMemoryRequirements2 memReqs = {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
|
||||
.pNext = &dedicatedReqs,
|
||||
};
|
||||
VkBufferMemoryRequirementsInfo2 bufferQuery = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
|
||||
.pNext = nullptr,
|
||||
.buffer = buffer,
|
||||
};
|
||||
vkGetBufferMemoryRequirements2(vulkanDevice, &bufferQuery, &memReqs);
|
||||
|
||||
memReqs.memoryRequirements.alignment =
|
||||
(16 > memReqs.memoryRequirements.alignment) ? 16 : memReqs.memoryRequirements.alignment;
|
||||
|
||||
stagingBuffer->allocation = allocator->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | (bCPURead ? VK_MEMORY_PROPERTY_HOST_COHERENT_BIT : VK_MEMORY_PROPERTY_HOST_CACHED_BIT), stagingBuffer->buffer);
|
||||
stagingBuffer->bReadable = bCPURead;
|
||||
stagingBuffer->size = size;
|
||||
stagingBuffer->usage = usage;
|
||||
vkBindBufferMemory(graphics->getDevice(), stagingBuffer->buffer, stagingBuffer->getMemoryHandle(), stagingBuffer->getOffset());
|
||||
|
||||
activeBuffers.add(stagingBuffer.getHandle());
|
||||
OStagingBuffer stagingBuffer = new StagingBuffer(
|
||||
allocator->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | (readable ? VK_MEMORY_PROPERTY_HOST_COHERENT_BIT : VK_MEMORY_PROPERTY_HOST_CACHED_BIT), buffer),
|
||||
buffer,
|
||||
usage,
|
||||
readable
|
||||
);
|
||||
vkBindBufferMemory(graphics->getDevice(), buffer, stagingBuffer->getMemoryHandle(), stagingBuffer->getOffset());
|
||||
|
||||
activeBuffers.add(stagingBuffer);
|
||||
|
||||
return stagingBuffer;
|
||||
}
|
||||
|
||||
void StagingManager::releaseStagingBuffer(PStagingBuffer buffer)
|
||||
void StagingManager::releaseStagingBuffer(OStagingBuffer buffer)
|
||||
{
|
||||
std::scoped_lock l(lock);
|
||||
freeBuffers.add(buffer);
|
||||
activeBuffers.remove(activeBuffers.find(buffer.getHandle()));
|
||||
activeBuffers.remove(buffer);
|
||||
freeBuffers.add(std::move(buffer));
|
||||
}
|
||||
@@ -10,29 +10,23 @@ namespace Seele
|
||||
namespace Vulkan
|
||||
{
|
||||
DECLARE_REF(Graphics)
|
||||
class Allocation;
|
||||
class Allocator;
|
||||
DECLARE_REF(Allocator)
|
||||
DECLARE_REF(Allocation)
|
||||
class SubAllocation
|
||||
{
|
||||
public:
|
||||
SubAllocation(Allocation *owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize);
|
||||
SubAllocation(PAllocation owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize);
|
||||
~SubAllocation();
|
||||
VkDeviceMemory getHandle() const;
|
||||
inline VkDeviceSize getSize() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
inline VkDeviceSize getOffset() const
|
||||
{
|
||||
return alignedOffset;
|
||||
}
|
||||
inline bool isReadable() const;
|
||||
constexpr VkDeviceMemory getHandle() const;
|
||||
constexpr VkDeviceSize getSize() const;
|
||||
constexpr VkDeviceSize getOffset() const;
|
||||
constexpr bool isReadable() const;
|
||||
void *getMappedPointer();
|
||||
void flushMemory();
|
||||
void invalidateMemory();
|
||||
|
||||
private:
|
||||
Allocation *owner;
|
||||
PAllocation owner;
|
||||
VkDeviceSize size;
|
||||
VkDeviceSize allocatedOffset;
|
||||
VkDeviceSize alignedOffset;
|
||||
@@ -44,54 +38,16 @@ DEFINE_REF(SubAllocation)
|
||||
class Allocation
|
||||
{
|
||||
public:
|
||||
Allocation(PGraphics graphics, Allocator *allocator, VkDeviceSize size, uint8 memoryTypeIndex,
|
||||
Allocation(PGraphics graphics, PAllocator allocator, VkDeviceSize size, uint8 memoryTypeIndex,
|
||||
VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo = nullptr);
|
||||
~Allocation();
|
||||
PSubAllocation getSuballocation(VkDeviceSize size, VkDeviceSize alignment);
|
||||
void markFree(SubAllocation *alloc);
|
||||
inline VkDeviceMemory getHandle() const
|
||||
{
|
||||
return allocatedMemory;
|
||||
}
|
||||
inline void *getMappedPointer()
|
||||
{
|
||||
if (!canMap)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (!isMapped)
|
||||
{
|
||||
vkMapMemory(device, allocatedMemory, 0, bytesAllocated, 0, &mappedPointer);
|
||||
isMapped = true;
|
||||
}
|
||||
return mappedPointer;
|
||||
}
|
||||
|
||||
inline bool isReadable() const
|
||||
{
|
||||
return readable;
|
||||
}
|
||||
|
||||
void flushMemory()
|
||||
{
|
||||
VkMappedMemoryRange range;
|
||||
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
|
||||
range.pNext = 0;
|
||||
range.memory = allocatedMemory;
|
||||
range.size = bytesAllocated;
|
||||
range.offset = 0;
|
||||
vkFlushMappedMemoryRanges(device, 1, &range);
|
||||
}
|
||||
|
||||
void invalidateMemory()
|
||||
{
|
||||
VkMappedMemoryRange range;
|
||||
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
|
||||
range.pNext = 0;
|
||||
range.memory = allocatedMemory;
|
||||
range.size = bytesAllocated;
|
||||
vkInvalidateMappedMemoryRanges(device, 1, &range);
|
||||
}
|
||||
OSubAllocation getSuballocation(VkDeviceSize size, VkDeviceSize alignment);
|
||||
void markFree(PSubAllocation alloc);
|
||||
constexpr VkDeviceMemory getHandle() const;
|
||||
constexpr void* getMappedPointer();
|
||||
constexpr bool isReadable() const;
|
||||
void flushMemory();
|
||||
void invalidateMemory();
|
||||
|
||||
private:
|
||||
VkDevice device;
|
||||
@@ -99,8 +55,8 @@ private:
|
||||
VkDeviceSize bytesAllocated;
|
||||
VkDeviceSize bytesUsed;
|
||||
VkDeviceMemory allocatedMemory;
|
||||
std::map<VkDeviceSize, PSubAllocation> activeAllocations;
|
||||
std::map<VkDeviceSize, PSubAllocation> freeRanges;
|
||||
Array<PSubAllocation> activeAllocations;
|
||||
Map<VkDeviceSize, OSubAllocation> freeRanges;
|
||||
std::mutex lock;
|
||||
void *mappedPointer;
|
||||
uint8 isDedicated : 1;
|
||||
@@ -142,7 +98,6 @@ public:
|
||||
}
|
||||
|
||||
void free(Allocation *allocation);
|
||||
void notifyUsageChanged(int64 usageChange);
|
||||
private:
|
||||
enum
|
||||
{
|
||||
@@ -152,7 +107,12 @@ private:
|
||||
{
|
||||
VkDeviceSize maxSize = 0;
|
||||
VkDeviceSize inUse = 0;
|
||||
Array<PAllocation> allocations;
|
||||
Array<OAllocation> allocations;
|
||||
HeapInfo() {}
|
||||
HeapInfo(const HeapInfo& other) = delete;
|
||||
HeapInfo(HeapInfo&& other) = default;
|
||||
HeapInfo& operator=(const HeapInfo& other) = delete;
|
||||
HeapInfo& operator=(HeapInfo&& other) = default;
|
||||
};
|
||||
Array<HeapInfo> heaps;
|
||||
uint32 findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties);
|
||||
@@ -161,52 +121,29 @@ private:
|
||||
VkPhysicalDeviceMemoryProperties memProperties;
|
||||
};
|
||||
DEFINE_REF(Allocator)
|
||||
|
||||
DECLARE_REF(StagingManager)
|
||||
class StagingBuffer
|
||||
{
|
||||
public:
|
||||
StagingBuffer();
|
||||
StagingBuffer(OSubAllocation allocation, VkBuffer buffer, VkBufferUsageFlags usage, uint8 readable);
|
||||
~StagingBuffer();
|
||||
void *getMappedPointer()
|
||||
{
|
||||
return allocation->getMappedPointer();
|
||||
}
|
||||
void flushMappedMemory()
|
||||
{
|
||||
allocation->flushMemory();
|
||||
}
|
||||
void invalidateMemory()
|
||||
{
|
||||
allocation->invalidateMemory();
|
||||
}
|
||||
VkBuffer getHandle() const
|
||||
void* getMappedPointer();
|
||||
void flushMappedMemory();
|
||||
void invalidateMemory();
|
||||
constexpr VkBuffer getHandle() const
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
VkDeviceMemory getMemoryHandle() const
|
||||
{
|
||||
return allocation->getHandle();
|
||||
}
|
||||
VkDeviceSize getOffset() const
|
||||
{
|
||||
return allocation->getOffset();
|
||||
}
|
||||
uint64 getSize() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
bool isReadable() const
|
||||
{
|
||||
return bReadable;
|
||||
}
|
||||
|
||||
constexpr VkDeviceMemory getMemoryHandle() const;
|
||||
constexpr VkDeviceSize getOffset() const;
|
||||
constexpr uint64 getSize() const;
|
||||
constexpr bool isReadable() const;
|
||||
constexpr VkBufferUsageFlags getUsage() const;
|
||||
private:
|
||||
PSubAllocation allocation;
|
||||
OSubAllocation allocation;
|
||||
VkBuffer buffer;
|
||||
uint64 size;
|
||||
VkBufferUsageFlags usage;
|
||||
uint8 bReadable;
|
||||
friend class StagingManager;
|
||||
uint8 readable;
|
||||
};
|
||||
DEFINE_REF(StagingBuffer)
|
||||
|
||||
@@ -215,15 +152,15 @@ class StagingManager
|
||||
public:
|
||||
StagingManager(PGraphics graphics, PAllocator allocator);
|
||||
~StagingManager();
|
||||
PStagingBuffer allocateStagingBuffer(uint64 size, VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, bool bCPURead = false);
|
||||
void releaseStagingBuffer(PStagingBuffer buffer);
|
||||
OStagingBuffer allocateStagingBuffer(uint64 size, VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, bool bCPURead = false);
|
||||
void releaseStagingBuffer(OStagingBuffer buffer);
|
||||
void clearPending();
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PAllocator allocator;
|
||||
Array<PStagingBuffer> freeBuffers;
|
||||
Array<StagingBuffer *> activeBuffers;
|
||||
Array<OStagingBuffer> freeBuffers;
|
||||
Array<PStagingBuffer> activeBuffers;
|
||||
std::mutex lock;
|
||||
};
|
||||
DEFINE_REF(StagingManager)
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#include "Buffer.h"
|
||||
#include "Initializer.h"
|
||||
#include "CommandBuffer.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
@@ -7,20 +9,20 @@ struct PendingBuffer
|
||||
{
|
||||
uint64 offset;
|
||||
uint64 size;
|
||||
PStagingBuffer stagingBuffer;
|
||||
OStagingBuffer stagingBuffer;
|
||||
Gfx::QueueType prevQueue;
|
||||
bool bWriteOnly;
|
||||
bool writeOnly;
|
||||
};
|
||||
|
||||
static std::map<Vulkan::Buffer*, PendingBuffer> pendingBuffers;
|
||||
|
||||
Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic)
|
||||
Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool dynamic)
|
||||
: graphics(graphics)
|
||||
, currentBuffer(0)
|
||||
, size(size)
|
||||
, owner(queueType)
|
||||
{
|
||||
if(bDynamic)
|
||||
if(dynamic)
|
||||
{
|
||||
numBuffers = Gfx::numFramesBuffered;
|
||||
}
|
||||
@@ -166,12 +168,12 @@ void Buffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlag
|
||||
vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
|
||||
}
|
||||
|
||||
void * Buffer::lock(bool bWriteOnly)
|
||||
void * Buffer::lock(bool writeOnly)
|
||||
{
|
||||
return lockRegion(0, size, bWriteOnly);
|
||||
return lockRegion(0, size, writeOnly);
|
||||
}
|
||||
|
||||
void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnly)
|
||||
void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly)
|
||||
{
|
||||
void *data = nullptr;
|
||||
|
||||
@@ -190,16 +192,16 @@ void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnl
|
||||
//assert(bStatic || bDynamic || bUAV);
|
||||
|
||||
PendingBuffer pending;
|
||||
pending.bWriteOnly = bWriteOnly;
|
||||
pending.writeOnly = writeOnly;
|
||||
pending.prevQueue = owner;
|
||||
pending.offset = regionOffset;
|
||||
pending.size = regionSize;
|
||||
if (bWriteOnly)
|
||||
if (writeOnly)
|
||||
{
|
||||
//requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
|
||||
PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(regionSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||
OStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(regionSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||
data = stagingBuffer->getMappedPointer();
|
||||
pending.stagingBuffer = stagingBuffer;
|
||||
pending.stagingBuffer = std::move(stagingBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -220,7 +222,7 @@ void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnl
|
||||
barrier.size = size;
|
||||
vkCmdPipelineBarrier(handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr);
|
||||
|
||||
PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true);
|
||||
OStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true);
|
||||
|
||||
VkBufferCopy regions;
|
||||
regions.size = size;
|
||||
@@ -233,11 +235,12 @@ void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnl
|
||||
vkQueueWaitIdle(graphics->getQueueCommands(owner)->getQueue()->getHandle());
|
||||
stagingBuffer->getMappedPointer(); // this maps the memory if not mapped already
|
||||
stagingBuffer->flushMappedMemory();
|
||||
pending.stagingBuffer = stagingBuffer;
|
||||
|
||||
data = stagingBuffer->getMappedPointer();
|
||||
|
||||
pending.stagingBuffer = std::move(stagingBuffer);
|
||||
|
||||
}
|
||||
pendingBuffers[this] = pending;
|
||||
pendingBuffers[this] = std::move(pending);
|
||||
|
||||
assert(data);
|
||||
return data;
|
||||
@@ -248,10 +251,9 @@ void Buffer::unlock()
|
||||
auto found = pendingBuffers.find(this);
|
||||
if (found != pendingBuffers.end())
|
||||
{
|
||||
PendingBuffer pending = found->second;
|
||||
PendingBuffer& pending = found->second;
|
||||
pending.stagingBuffer->flushMappedMemory();
|
||||
pendingBuffers.erase(this);
|
||||
if (pending.bWriteOnly)
|
||||
if (pending.writeOnly)
|
||||
{
|
||||
PStagingBuffer stagingBuffer = pending.stagingBuffer;
|
||||
PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
|
||||
@@ -265,16 +267,17 @@ void Buffer::unlock()
|
||||
graphics->getQueueCommands(owner)->submitCommands();
|
||||
}
|
||||
//requestOwnershipTransfer(pending.prevQueue);
|
||||
graphics->getStagingManager()->releaseStagingBuffer(pending.stagingBuffer);
|
||||
graphics->getStagingManager()->releaseStagingBuffer(std::move(pending.stagingBuffer));
|
||||
pendingBuffers.erase(this);
|
||||
}
|
||||
}
|
||||
|
||||
UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &createInfo)
|
||||
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData)
|
||||
, Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, createInfo.bDynamic)
|
||||
, Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, createInfo.dynamic)
|
||||
, dedicatedStagingBuffer(nullptr)
|
||||
{
|
||||
if(createInfo.bDynamic)
|
||||
if(createInfo.dynamic)
|
||||
{
|
||||
dedicatedStagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(createInfo.sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||
}
|
||||
@@ -302,13 +305,13 @@ bool UniformBuffer::updateContents(const DataSource &sourceData)
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
void* UniformBuffer::lock(bool bWriteOnly)
|
||||
void* UniformBuffer::lock(bool writeOnly)
|
||||
{
|
||||
if(dedicatedStagingBuffer != nullptr)
|
||||
{
|
||||
return dedicatedStagingBuffer->getMappedPointer();
|
||||
}
|
||||
return Vulkan::Buffer::lock(bWriteOnly);
|
||||
return Vulkan::Buffer::lock(writeOnly);
|
||||
}
|
||||
|
||||
void UniformBuffer::unlock()
|
||||
@@ -359,7 +362,7 @@ VkAccessFlags UniformBuffer::getDestAccessMask()
|
||||
|
||||
ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &sourceData)
|
||||
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), sourceData.stride, sourceData.sourceData.size / sourceData.stride, sourceData.sourceData)
|
||||
, Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, sourceData.bDynamic)
|
||||
, Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, sourceData.dynamic)
|
||||
{
|
||||
if (sourceData.sourceData.data != nullptr)
|
||||
{
|
||||
@@ -383,13 +386,13 @@ bool ShaderBuffer::updateContents(const DataSource &sourceData)
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
void* ShaderBuffer::lock(bool bWriteOnly)
|
||||
void* ShaderBuffer::lock(bool writeOnly)
|
||||
{
|
||||
if(dedicatedStagingBuffer != nullptr)
|
||||
{
|
||||
return dedicatedStagingBuffer->getMappedPointer();
|
||||
}
|
||||
return ShaderBuffer::lock(bWriteOnly);
|
||||
return ShaderBuffer::lock(writeOnly);
|
||||
}
|
||||
|
||||
void ShaderBuffer::unlock()
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Vulkan
|
||||
class Buffer
|
||||
{
|
||||
public:
|
||||
Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false);
|
||||
Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool dynamic = false);
|
||||
virtual ~Buffer();
|
||||
VkBuffer getHandle() const
|
||||
{
|
||||
@@ -26,8 +26,8 @@ public:
|
||||
{
|
||||
currentBuffer = (currentBuffer + 1) % numBuffers;
|
||||
}
|
||||
virtual void *lock(bool bWriteOnly = true);
|
||||
virtual void *lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnly = true);
|
||||
virtual void *lock(bool writeOnly = true);
|
||||
virtual void *lockRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly = true);
|
||||
virtual void unlock();
|
||||
|
||||
protected:
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
virtual ~UniformBuffer();
|
||||
virtual bool updateContents(const DataSource &sourceData);
|
||||
|
||||
virtual void* lock(bool bWriteOnly = true) override;
|
||||
virtual void* lock(bool writeOnly = true) override;
|
||||
virtual void unlock() override;
|
||||
protected:
|
||||
// Inherited via Vulkan::Buffer
|
||||
@@ -75,7 +75,7 @@ protected:
|
||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
|
||||
|
||||
private:
|
||||
PStagingBuffer dedicatedStagingBuffer;
|
||||
OStagingBuffer dedicatedStagingBuffer;
|
||||
};
|
||||
DEFINE_REF(UniformBuffer)
|
||||
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
virtual ~ShaderBuffer();
|
||||
virtual bool updateContents(const DataSource &sourceData);
|
||||
|
||||
virtual void* lock(bool bWriteOnly = true) override;
|
||||
virtual void* lock(bool writeOnly = true) override;
|
||||
virtual void unlock() override;
|
||||
protected:
|
||||
// Inherited via Vulkan::Buffer
|
||||
@@ -98,7 +98,7 @@ protected:
|
||||
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
|
||||
private:
|
||||
PStagingBuffer dedicatedStagingBuffer;
|
||||
OStagingBuffer dedicatedStagingBuffer;
|
||||
};
|
||||
DEFINE_REF(ShaderBuffer)
|
||||
|
||||
|
||||
@@ -313,7 +313,7 @@ void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount, int32 firstVe
|
||||
void RenderCommand::dispatch(uint32 groupX, uint32 groupY, uint32 groupZ)
|
||||
{
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
vkCmdDrawMeshTasksEXT(handle, groupX, groupY, groupZ);
|
||||
graphics->vkCmdDrawMeshTasksEXT(handle, groupX, groupY, groupZ);
|
||||
}
|
||||
|
||||
ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool)
|
||||
@@ -524,4 +524,4 @@ void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
|
||||
allocatedBuffers.add(new CmdBuffer(graphics, commandPool, this));
|
||||
activeCmdBuffer = allocatedBuffers.back();
|
||||
activeCmdBuffer->begin();
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "Graphics.h"
|
||||
#include "Initializer.h"
|
||||
#include "CommandBuffer.h"
|
||||
#include "Texture.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
@@ -130,12 +131,12 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBu
|
||||
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, binding, &bufferInfos.back());
|
||||
writeDescriptors.add(writeDescriptor);
|
||||
|
||||
cachedData[binding] = new UniformBuffer(*vulkanBuffer.getHandle());
|
||||
cachedData[binding] = vulkanBuffer.getHandle();
|
||||
}
|
||||
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer ShaderBuffer)
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuffer)
|
||||
{
|
||||
PShaderBuffer vulkanBuffer = ShaderBuffer.cast<ShaderBuffer>();
|
||||
PShaderBuffer vulkanBuffer = shaderBuffer.cast<ShaderBuffer>();
|
||||
ShaderBuffer* cachedBuffer = reinterpret_cast<ShaderBuffer*>(cachedData[binding]);
|
||||
if(vulkanBuffer.getHandle() == cachedBuffer)
|
||||
{
|
||||
@@ -349,21 +350,20 @@ Gfx::PDescriptorSet DescriptorAllocator::allocateDescriptorSet()
|
||||
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &cachedHandles[setIndex]->setHandle));
|
||||
}
|
||||
cachedHandles[setIndex]->allocate();
|
||||
descriptorSet = cachedHandles[setIndex];
|
||||
|
||||
PDescriptorSet vulkanSet = descriptorSet.cast<DescriptorSet>();
|
||||
PDescriptorSet vulkanSet = cachedHandles[setIndex];
|
||||
vulkanSet->cachedData.resize(layout.bindings.size());
|
||||
// Not really pretty, but this way the set knows which ones are valid
|
||||
std::memset(vulkanSet->cachedData.data(), 0, sizeof(void*) * vulkanSet->cachedData.size());
|
||||
|
||||
//Found set, stop searching
|
||||
return;
|
||||
return vulkanSet;
|
||||
}
|
||||
if(nextAlloc == nullptr)
|
||||
{
|
||||
nextAlloc = new DescriptorAllocator(graphics, layout);
|
||||
}
|
||||
nextAlloc->allocateDescriptorSet(descriptorSet);
|
||||
return nextAlloc->allocateDescriptorSet();
|
||||
//throw std::logic_error("Out of descriptor sets");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "Enums.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "RenderTarget.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Framebuffer.h"
|
||||
#include "Shader.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
using namespace Seele;
|
||||
@@ -134,8 +135,8 @@ Gfx::OUniformBuffer Graphics::createUniformBuffer(const UniformBufferCreateInfo
|
||||
|
||||
Gfx::OShaderBuffer Graphics::createShaderBuffer(const ShaderBufferCreateInfo &bulkData)
|
||||
{
|
||||
OShaderBuffer ShaderBuffer = new ShaderBuffer(this, bulkData);
|
||||
return ShaderBuffer;
|
||||
OShaderBuffer shaderBuffer = new ShaderBuffer(this, bulkData);
|
||||
return shaderBuffer;
|
||||
}
|
||||
Gfx::OVertexBuffer Graphics::createVertexBuffer(const VertexBufferCreateInfo &bulkData)
|
||||
{
|
||||
@@ -150,13 +151,13 @@ Gfx::OIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkD
|
||||
}
|
||||
Gfx::PRenderCommand Graphics::createRenderCommand(const std::string& name)
|
||||
{
|
||||
ORenderCommand cmdBuffer = getGraphicsCommands()->createRenderCommand(activeRenderPass, activeFramebuffer, name);
|
||||
PRenderCommand cmdBuffer = getGraphicsCommands()->createRenderCommand(activeRenderPass, activeFramebuffer, name);
|
||||
return cmdBuffer;
|
||||
}
|
||||
|
||||
Gfx::PComputeCommand Graphics::createComputeCommand(const std::string& name)
|
||||
{
|
||||
OComputeCommand cmdBuffer = getComputeCommands()->createComputeCommand(name);
|
||||
PComputeCommand cmdBuffer = getComputeCommands()->createComputeCommand(name);
|
||||
return cmdBuffer;
|
||||
}
|
||||
|
||||
@@ -172,52 +173,51 @@ Gfx::OVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createIn
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
Gfx::PControlShader Graphics::createControlShader(const ShaderCreateInfo& createInfo)
|
||||
Gfx::OFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
PControlShader shader = new ControlShader(this);
|
||||
OFragmentShader shader = new FragmentShader(this);
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
Gfx::PEvaluationShader Graphics::createEvaluationShader(const ShaderCreateInfo& createInfo)
|
||||
Gfx::OComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
PEvaluationShader shader = new EvaluationShader(this);
|
||||
OComputeShader shader = new ComputeShader(this);
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
Gfx::PGeometryShader Graphics::createGeometryShader(const ShaderCreateInfo& createInfo)
|
||||
Gfx::OTaskShader Graphics::createTaskShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
PGeometryShader shader = new GeometryShader(this);
|
||||
OTaskShader shader = new TaskShader(this);
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
Gfx::PFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo)
|
||||
Gfx::OMeshShader Graphics::createMeshShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
PFragmentShader shader = new FragmentShader(this);
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
Gfx::PComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
PComputeShader shader = new ComputeShader(this);
|
||||
OMeshShader shader = new MeshShader(this);
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
|
||||
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo)
|
||||
Gfx::OGraphicsPipeline Graphics::createGraphicsPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo)
|
||||
{
|
||||
PGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo);
|
||||
OGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo);
|
||||
return pipeline;
|
||||
}
|
||||
Gfx::OGraphicsPipeline Graphics::createGraphicsPipeline(const Gfx::MeshPipelineCreateInfo& createInfo)
|
||||
{
|
||||
OGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo);
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
Gfx::PComputePipeline Graphics::createComputePipeline(const ComputePipelineCreateInfo& createInfo)
|
||||
Gfx::OComputePipeline Graphics::createComputePipeline(const Gfx::ComputePipelineCreateInfo& createInfo)
|
||||
{
|
||||
PComputePipeline pipeline = pipelineCache->createPipeline(createInfo);
|
||||
OComputePipeline pipeline = pipelineCache->createPipeline(createInfo);
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
Gfx::PSamplerState Graphics::createSamplerState(const SamplerCreateInfo& createInfo)
|
||||
Gfx::OSamplerState Graphics::createSamplerState(const SamplerCreateInfo& createInfo)
|
||||
{
|
||||
PSamplerState sampler = new SamplerState();
|
||||
OSamplerState sampler = new SamplerState();
|
||||
VkSamplerCreateInfo vkInfo =
|
||||
init::SamplerCreateInfo();
|
||||
vkInfo.addressModeU = cast(createInfo.addressModeU);
|
||||
@@ -239,14 +239,14 @@ Gfx::PSamplerState Graphics::createSamplerState(const SamplerCreateInfo& createI
|
||||
VK_CHECK(vkCreateSampler(handle, &vkInfo, nullptr, &sampler->sampler));
|
||||
return sampler;
|
||||
}
|
||||
Gfx::PDescriptorLayout Graphics::createDescriptorLayout(const std::string& name)
|
||||
Gfx::ODescriptorLayout Graphics::createDescriptorLayout(const std::string& name)
|
||||
{
|
||||
PDescriptorLayout layout = new DescriptorLayout(this, name);
|
||||
ODescriptorLayout layout = new DescriptorLayout(this, name);
|
||||
return layout;
|
||||
}
|
||||
Gfx::PPipelineLayout Graphics::createPipelineLayout(Gfx::PPipelineLayout baseLayout)
|
||||
Gfx::OPipelineLayout Graphics::createPipelineLayout(Gfx::PPipelineLayout baseLayout)
|
||||
{
|
||||
PPipelineLayout layout = new PipelineLayout(this, baseLayout);
|
||||
OPipelineLayout layout = new PipelineLayout(this, baseLayout);
|
||||
return layout;
|
||||
}
|
||||
|
||||
@@ -317,6 +317,10 @@ void Graphics::copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture)
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint32 groupY, uint32 groupZ)
|
||||
{
|
||||
cmdDrawMeshTasks(handle, groupX, groupY, groupZ);
|
||||
}
|
||||
PCommandBufferManager Graphics::getQueueCommands(Gfx::QueueType queueType)
|
||||
{
|
||||
switch (queueType)
|
||||
@@ -361,7 +365,7 @@ PCommandBufferManager Graphics::getDedicatedTransferCommands()
|
||||
{
|
||||
if(dedicatedTransferCommands == nullptr)
|
||||
{
|
||||
dedicatedTransferCommands = new CommandBufferManager(this, dedicatedTransferQueue);
|
||||
dedicatedTransferCommands = new CommandBufferManager(this, dedicatedTransferQueue != nullptr ? dedicatedTransferQueue : transferQueue);
|
||||
}
|
||||
return dedicatedTransferCommands;
|
||||
}
|
||||
@@ -441,7 +445,7 @@ void Graphics::pickPhysicalDevice()
|
||||
{
|
||||
uint32 currentRating = 0;
|
||||
vkGetPhysicalDeviceProperties(dev, &props);
|
||||
vkGetPhysicalDeviceFeatures(dev, &features);
|
||||
vkGetPhysicalDeviceFeatures2(dev, &features);
|
||||
if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
||||
{
|
||||
std::cout << "found dedicated gpu " << props.deviceName << std::endl;
|
||||
@@ -461,7 +465,7 @@ void Graphics::pickPhysicalDevice()
|
||||
}
|
||||
physicalDevice = bestDevice;
|
||||
vkGetPhysicalDeviceProperties(physicalDevice, &props);
|
||||
vkGetPhysicalDeviceFeatures(physicalDevice, &features);
|
||||
vkGetPhysicalDeviceFeatures2(physicalDevice, &features);
|
||||
}
|
||||
|
||||
void Graphics::createDevice(GraphicsInitializer initializer)
|
||||
@@ -563,13 +567,13 @@ void Graphics::createDevice(GraphicsInitializer initializer)
|
||||
(uint32)queueInfos.size(),
|
||||
&features);
|
||||
|
||||
VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexing = {};
|
||||
std::memset(&descriptorIndexing, 0, sizeof(descriptorIndexing));
|
||||
descriptorIndexing.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES;
|
||||
descriptorIndexing.shaderSampledImageArrayNonUniformIndexing = VK_TRUE;
|
||||
descriptorIndexing.runtimeDescriptorArray = VK_TRUE;
|
||||
descriptorIndexing.descriptorBindingVariableDescriptorCount = VK_TRUE;
|
||||
descriptorIndexing.descriptorBindingPartiallyBound = VK_TRUE;
|
||||
VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexing = {
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES,
|
||||
.shaderSampledImageArrayNonUniformIndexing = VK_TRUE,
|
||||
.descriptorBindingPartiallyBound = VK_TRUE,
|
||||
.descriptorBindingVariableDescriptorCount = VK_TRUE,
|
||||
.runtimeDescriptorArray = VK_TRUE,
|
||||
};
|
||||
deviceInfo.pNext = &descriptorIndexing;
|
||||
#if ENABLE_VALIDATION
|
||||
VkDeviceDiagnosticsConfigCreateInfoNV crashDiagInfo;
|
||||
@@ -581,6 +585,18 @@ void Graphics::createDevice(GraphicsInitializer initializer)
|
||||
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,
|
||||
.meshShader = VK_TRUE,
|
||||
};
|
||||
if (Gfx::useMeshShading)
|
||||
{
|
||||
descriptorIndexing.pNext = &enabledMeshShaderFeatures;
|
||||
initializer.deviceExtensions.add("VK_EXT_mesh_shader");
|
||||
initializer.deviceExtensions.add("VK_KHR_SPIRV_1_4_EXTENSION_NAME");
|
||||
initializer.deviceExtensions.add("VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME");
|
||||
}
|
||||
deviceInfo.enabledExtensionCount = (uint32)initializer.deviceExtensions.size();
|
||||
deviceInfo.ppEnabledExtensionNames = initializer.deviceExtensions.data();
|
||||
deviceInfo.enabledLayerCount = (uint32_t)initializer.layers.size();
|
||||
@@ -590,6 +606,8 @@ void Graphics::createDevice(GraphicsInitializer initializer)
|
||||
VK_CHECK(vkCreateDevice(physicalDevice, &deviceInfo, nullptr, &handle));
|
||||
std::cout << "Vulkan handle: " << handle << std::endl;
|
||||
|
||||
cmdDrawMeshTasks = (PFN_vkCmdDrawMeshTasksEXT)vkGetDeviceProcAddr(handle, "vkCmdDrawMeshTasksEXT");
|
||||
|
||||
graphicsQueue = new Queue(this, Gfx::QueueType::GRAPHICS, graphicsQueueInfo.familyIndex, 0);
|
||||
if (Gfx::useAsyncCompute && asyncComputeInfo.familyIndex != -1)
|
||||
{
|
||||
@@ -613,12 +631,8 @@ void Graphics::createDevice(GraphicsInitializer initializer)
|
||||
{
|
||||
dedicatedTransferQueue = new Queue(this, Gfx::QueueType::DEDICATED_TRANSFER, dedicatedTransferQueueInfo.familyIndex, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
dedicatedTransferQueue = transferQueue;
|
||||
}
|
||||
queueMapping.graphicsFamily = graphicsQueue->getFamilyIndex();
|
||||
queueMapping.computeFamily = computeQueue->getFamilyIndex();
|
||||
queueMapping.transferFamily = transferQueue->getFamilyIndex();
|
||||
queueMapping.dedicatedTransferFamily = dedicatedTransferQueue->getFamilyIndex();
|
||||
queueMapping.dedicatedTransferFamily = dedicatedTransferQueue != nullptr ? dedicatedTransferQueue->getFamilyIndex() : transferQueue->getFamilyIndex();
|
||||
}
|
||||
|
||||
@@ -73,7 +73,9 @@ public:
|
||||
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;
|
||||
Array<const char *> getRequiredExtensions();
|
||||
void initInstance(GraphicsInitializer initInfo);
|
||||
void setupDebugCallback();
|
||||
@@ -97,7 +99,7 @@ protected:
|
||||
thread_local static OCommandBufferManager transferCommands;
|
||||
thread_local static OCommandBufferManager dedicatedTransferCommands;
|
||||
VkPhysicalDeviceProperties props;
|
||||
VkPhysicalDeviceFeatures features;
|
||||
VkPhysicalDeviceFeatures2 features;
|
||||
VkDebugReportCallbackEXT callback;
|
||||
std::mutex viewportLock;
|
||||
Array<PViewport> viewports;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "Initializer.h"
|
||||
#include <iostream>
|
||||
#include "Initializer.h"
|
||||
#include "Initializer.h"
|
||||
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
|
||||
@@ -51,6 +51,11 @@ VkDeviceCreateInfo DeviceCreateInfo(
|
||||
uint32_t queueCount,
|
||||
VkPhysicalDeviceFeatures *features);
|
||||
|
||||
VkDeviceCreateInfo DeviceCreateInfo(
|
||||
VkDeviceQueueCreateInfo* queueInfos,
|
||||
uint32_t queueCount,
|
||||
VkPhysicalDeviceFeatures2* features);
|
||||
|
||||
VkSwapchainCreateInfoKHR SwapchainCreateInfo(
|
||||
VkSurfaceKHR surface,
|
||||
uint32_t minImageCount,
|
||||
|
||||
@@ -48,7 +48,7 @@ PipelineCache::~PipelineCache()
|
||||
std::cout << "Written " << cacheSize << " bytes to cache" << std::endl;
|
||||
}
|
||||
|
||||
PGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateInfo& gfxInfo)
|
||||
OGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateInfo& gfxInfo)
|
||||
{
|
||||
uint32 stageCount = 0;
|
||||
|
||||
@@ -99,7 +99,7 @@ PGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateI
|
||||
*res = VkVertexInputBindingDescription{
|
||||
.binding = elem.binding,
|
||||
.stride = elem.stride,
|
||||
.inputRate = elem.bInstanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX,
|
||||
.inputRate = elem.instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX,
|
||||
};
|
||||
}
|
||||
vertexInput.pVertexAttributeDescriptions = attributes.data();
|
||||
@@ -217,12 +217,12 @@ PGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateI
|
||||
std::cout << "Gfx creation time: " << delta << std::endl;
|
||||
|
||||
|
||||
PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout);
|
||||
OGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
PGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInfo& gfxInfo)
|
||||
OGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInfo& gfxInfo)
|
||||
{
|
||||
uint32 stageCount = 0;
|
||||
|
||||
@@ -361,33 +361,35 @@ PGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInf
|
||||
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - beginTime).count();
|
||||
std::cout << "Gfx creation time: " << delta << std::endl;
|
||||
|
||||
|
||||
PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout);
|
||||
OGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
PComputePipeline PipelineCache::createPipeline(const Gfx::ComputePipelineCreateInfo& computeInfo)
|
||||
OComputePipeline PipelineCache::createPipeline(const Gfx::ComputePipelineCreateInfo& computeInfo)
|
||||
{
|
||||
VkComputePipelineCreateInfo createInfo;
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
|
||||
createInfo.pNext = 0;
|
||||
createInfo.flags = 0;
|
||||
createInfo.basePipelineIndex = 0;
|
||||
createInfo.basePipelineHandle = VK_NULL_HANDLE;
|
||||
auto layout = computeInfo.pipelineLayout.cast<PipelineLayout>();
|
||||
createInfo.layout = layout->getHandle();
|
||||
auto computeStage = computeInfo.computeShader.cast<ComputeShader>();
|
||||
createInfo.stage = init::PipelineShaderStageCreateInfo(
|
||||
VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
computeStage->getModuleHandle(),
|
||||
computeStage->getEntryPointName());
|
||||
|
||||
VkComputePipelineCreateInfo createInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
|
||||
.pNext = 0,
|
||||
.flags = 0,
|
||||
.stage = init::PipelineShaderStageCreateInfo(
|
||||
VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
computeStage->getModuleHandle(),
|
||||
computeStage->getEntryPointName()),
|
||||
.layout = layout->getHandle(),
|
||||
.basePipelineHandle = VK_NULL_HANDLE,
|
||||
.basePipelineIndex = 0,
|
||||
};
|
||||
|
||||
VkPipeline pipelineHandle;
|
||||
auto beginTime = std::chrono::high_resolution_clock::now();
|
||||
VK_CHECK(vkCreateComputePipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle));
|
||||
auto endTime = std::chrono::high_resolution_clock::now();
|
||||
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - beginTime).count();
|
||||
std::cout << "Compute creation time: " << delta << std::endl;
|
||||
PComputePipeline result = new ComputePipeline(graphics, pipelineHandle, layout);
|
||||
OComputePipeline result = new ComputePipeline(graphics, pipelineHandle, layout);
|
||||
return result;
|
||||
}
|
||||
@@ -10,9 +10,9 @@ class PipelineCache
|
||||
public:
|
||||
PipelineCache(PGraphics graphics, const std::string& cacheFilePath);
|
||||
~PipelineCache();
|
||||
PGraphicsPipeline createPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo);
|
||||
PGraphicsPipeline createPipeline(const Gfx::MeshPipelineCreateInfo& createInfo);
|
||||
PComputePipeline createPipeline(const Gfx::ComputePipelineCreateInfo& createInfo);
|
||||
OGraphicsPipeline createPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo);
|
||||
OGraphicsPipeline createPipeline(const Gfx::MeshPipelineCreateInfo& createInfo);
|
||||
OComputePipeline createPipeline(const Gfx::ComputePipelineCreateInfo& createInfo);
|
||||
private:
|
||||
VkPipelineCache cache;
|
||||
PGraphics graphics;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Graphics.h"
|
||||
#include "Framebuffer.h"
|
||||
#include "Texture.h"
|
||||
#include "RenderPass.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
@@ -143,4 +144,5 @@ uint32 RenderPass::getFramebufferHash()
|
||||
description.depthAttachment = tex->getView();
|
||||
}
|
||||
return CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "VulkanAllocator.h"
|
||||
#include "VulkanCommandBuffer.h"
|
||||
#include "Graphics/GraphicsEnums.h"
|
||||
#include "Texture.h"
|
||||
#include "Initializer.h"
|
||||
#include "CommandBuffer.h"
|
||||
#include <math.h>
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
@@ -9,23 +9,23 @@ Material::Material()
|
||||
{
|
||||
}
|
||||
|
||||
Material::Material(Gfx::PGraphics graphics,
|
||||
Array<OShaderParameter> parameter,
|
||||
Material::Material(Gfx::PGraphics graphics,
|
||||
Gfx::ODescriptorLayout layout,
|
||||
uint32 uniformDataSize,
|
||||
uint32 uniformBinding,
|
||||
std::string materialName,
|
||||
Array<OShaderExpression> expressions,
|
||||
Map<std::string, OShaderExpression> expressions,
|
||||
Array<std::string> parameter,
|
||||
MaterialNode brdf)
|
||||
: graphics(graphics)
|
||||
, parameters(std::move(parameter))
|
||||
, uniformDataSize(uniformDataSize)
|
||||
, uniformBinding(uniformBinding)
|
||||
, instanceId(0)
|
||||
, layout(std::move(layout))
|
||||
, materialName(materialName)
|
||||
, codeExpressions(std::move(expressions))
|
||||
, brdf(brdf)
|
||||
, instanceId(0)
|
||||
, parameters(std::move(parameter))
|
||||
, brdf(std::move(brdf))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -33,14 +33,19 @@ Material::~Material()
|
||||
{
|
||||
}
|
||||
|
||||
PMaterialInstance Seele::Material::instantiate()
|
||||
OMaterialInstance Material::instantiate()
|
||||
{
|
||||
return new MaterialInstance(instanceId++, graphics, this, layout, parameters, uniformBinding, uniformDataSize);
|
||||
return new MaterialInstance(
|
||||
instanceId++,
|
||||
graphics,
|
||||
codeExpressions,
|
||||
parameters,
|
||||
uniformBinding,
|
||||
uniformDataSize);
|
||||
}
|
||||
|
||||
void Material::save(ArchiveBuffer& buffer) const
|
||||
{
|
||||
Serialization::save(buffer, brdfName);
|
||||
Serialization::save(buffer, uniformDataSize);
|
||||
Serialization::save(buffer, uniformBinding);
|
||||
Serialization::save(buffer, instanceId);
|
||||
@@ -59,13 +64,11 @@ void Material::save(ArchiveBuffer& buffer) const
|
||||
Serialization::save(buffer, binding.descriptorType);
|
||||
Serialization::save(buffer, binding.shaderStages);
|
||||
}
|
||||
Serialization::save(buffer, instances);
|
||||
}
|
||||
|
||||
void Material::load(ArchiveBuffer& buffer)
|
||||
{
|
||||
graphics = buffer.getGraphics();
|
||||
Serialization::load(buffer, brdfName);
|
||||
Serialization::load(buffer, uniformDataSize);
|
||||
Serialization::load(buffer, uniformBinding);
|
||||
Serialization::load(buffer, instanceId);
|
||||
@@ -98,11 +101,6 @@ void Material::load(ArchiveBuffer& buffer)
|
||||
layout->addDescriptorBinding(binding, descriptorType, descriptorCount, bindingFlags, shaderStages);
|
||||
}
|
||||
layout->create();
|
||||
Serialization::load(buffer, instances);
|
||||
for (auto& instance : instances)
|
||||
{
|
||||
instance->setBaseMaterial(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Material::compile()
|
||||
@@ -114,21 +112,23 @@ void Material::compile()
|
||||
codeStream << "struct " << materialName << " : IMaterial {\n";
|
||||
for(const auto& parameter : parameters)
|
||||
{
|
||||
parameter->generateDeclaration(codeStream);
|
||||
PShaderParameter handle = PShaderExpression(codeExpressions[parameter]);
|
||||
handle->generateDeclaration(codeStream);
|
||||
}
|
||||
codeStream << "\ttypedef " << brdf.profile << " BRDF;\n";
|
||||
codeStream << "\t" << brdf.profile << " prepare(MaterialFragmentParameter input) {\n";
|
||||
codeStream << "\t\t" << brdf.profile << " result;\n";
|
||||
Map<int32, std::string> varState;
|
||||
for(const auto& expr : codeExpressions)
|
||||
Map<std::string, std::string> varState;
|
||||
for(const auto& [_, expr] :codeExpressions)
|
||||
{
|
||||
codeStream << expr->evaluate(varState);
|
||||
}
|
||||
for(const auto& [name, exp] : brdf.variables)
|
||||
{
|
||||
codeStream << "\t\tresult." << name << " = " << varState[exp->key] << ";";
|
||||
codeStream << "\t\tresult." << name << " = " << varState[exp] << ";";
|
||||
}
|
||||
codeStream << "\t\treturn result;\n";
|
||||
codeStream << "\t}\n";
|
||||
codeStream << "};\n";
|
||||
graphics->getShaderCompiler()->registerMaterial(this);
|
||||
}
|
||||
|
||||
@@ -9,18 +9,17 @@ class Material
|
||||
{
|
||||
public:
|
||||
Material();
|
||||
Material(Gfx::PGraphics graphics,
|
||||
Array<OShaderParameter> parameter,
|
||||
Material(Gfx::PGraphics graphics,
|
||||
Gfx::ODescriptorLayout layout,
|
||||
uint32 uniformDataSize,
|
||||
uint32 uniformBinding,
|
||||
std::string materialName,
|
||||
Array<OShaderExpression> expressions,
|
||||
Map<std::string, OShaderExpression> expressions,
|
||||
Array<std::string> parameter,
|
||||
MaterialNode brdf);
|
||||
~Material();
|
||||
const Gfx::PDescriptorLayout getDescriptorLayout() const { return layout; }
|
||||
PMaterialInstance instantiate();
|
||||
PMaterialInstance getInstance(uint64 instance) { return instances[instance]; }
|
||||
OMaterialInstance instantiate();
|
||||
const std::string& getName() const { return materialName; }
|
||||
|
||||
void save(ArchiveBuffer& buffer) const;
|
||||
@@ -30,15 +29,13 @@ public:
|
||||
|
||||
private:
|
||||
Gfx::PGraphics graphics;
|
||||
std::string brdfName;
|
||||
uint32 uniformDataSize;
|
||||
uint32 uniformBinding;
|
||||
uint64 instanceId;
|
||||
Gfx::ODescriptorLayout layout;
|
||||
std::string materialName;
|
||||
Array<OShaderExpression> codeExpressions;
|
||||
Array<OShaderParameter> parameters;
|
||||
Array<OMaterialInstance> instances;
|
||||
Map<std::string, OShaderExpression> codeExpressions;
|
||||
Array<std::string> parameters;
|
||||
MaterialNode brdf;
|
||||
};
|
||||
DEFINE_REF(Material)
|
||||
|
||||
@@ -8,17 +8,34 @@ MaterialInstance::MaterialInstance()
|
||||
{
|
||||
}
|
||||
|
||||
MaterialInstance::MaterialInstance(uint64 id, Gfx::PGraphics graphics, PMaterial baseMaterial, Gfx::PDescriptorLayout layout, Array<OShaderParameter> params, uint32 uniformBinding, uint32 uniformSize)
|
||||
: id(id), graphics(graphics), baseMaterial(baseMaterial), layout(layout), parameters(params), uniformBinding(uniformBinding)
|
||||
MaterialInstance::MaterialInstance(uint64 id,
|
||||
Gfx::PGraphics graphics,
|
||||
Map<std::string, OShaderExpression>& expressions,
|
||||
Array<std::string> params,
|
||||
uint32 uniformBinding,
|
||||
uint32 uniformSize)
|
||||
: id(id)
|
||||
, graphics(graphics)
|
||||
, uniformBinding(uniformBinding)
|
||||
{
|
||||
uniformBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = uniformSize,
|
||||
},
|
||||
.bDynamic = true,
|
||||
.dynamic = true,
|
||||
}
|
||||
);
|
||||
uniformData.resize(uniformSize);
|
||||
ArchiveBuffer buffer(graphics);
|
||||
parameters.reserve(params.size());
|
||||
for (int i = 0; i < params.size(); ++i)
|
||||
{
|
||||
Serialization::save(buffer, params[i]);
|
||||
buffer.rewind();
|
||||
OShaderParameter param;
|
||||
Serialization::load(buffer, param);
|
||||
parameters.add(std::move(param));
|
||||
}
|
||||
}
|
||||
|
||||
MaterialInstance::~MaterialInstance()
|
||||
@@ -28,6 +45,8 @@ MaterialInstance::~MaterialInstance()
|
||||
|
||||
void MaterialInstance::updateDescriptor()
|
||||
{
|
||||
Gfx::PDescriptorLayout layout = baseMaterial->getMaterial()->getDescriptorLayout();
|
||||
layout->reset();
|
||||
descriptor = layout->allocateDescriptorSet();
|
||||
for (auto& param : parameters)
|
||||
{
|
||||
@@ -36,16 +55,27 @@ void MaterialInstance::updateDescriptor()
|
||||
descriptor->writeChanges();
|
||||
}
|
||||
|
||||
Gfx::PDescriptorSet Seele::MaterialInstance::getDescriptorSet() const
|
||||
Gfx::PDescriptorSet MaterialInstance::getDescriptorSet() const
|
||||
{
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
void MaterialInstance::setBaseMaterial(PMaterialAsset asset)
|
||||
{
|
||||
uniformBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = uniformData.size(),
|
||||
},
|
||||
.dynamic = true,
|
||||
}
|
||||
);
|
||||
baseMaterial = asset;
|
||||
}
|
||||
|
||||
void MaterialInstance::save(ArchiveBuffer& buffer) const
|
||||
{
|
||||
Serialization::save(buffer, uniformData);
|
||||
Serialization::save(buffer, uniformBinding);
|
||||
Serialization::save(buffer, uniformBuffer);
|
||||
Serialization::save(buffer, parameters);
|
||||
Serialization::save(buffer, id);
|
||||
}
|
||||
@@ -55,19 +85,6 @@ void MaterialInstance::load(ArchiveBuffer& buffer)
|
||||
graphics = buffer.getGraphics();
|
||||
Serialization::load(buffer, uniformData);
|
||||
Serialization::load(buffer, uniformBinding);
|
||||
Serialization::load(buffer, uniformBuffer);
|
||||
Serialization::load(buffer, parameters);
|
||||
Serialization::load(buffer, id);
|
||||
}
|
||||
|
||||
void MaterialInstance::setBaseMaterial(PMaterial material)
|
||||
{
|
||||
layout = material->getDescriptorLayout();
|
||||
baseMaterial = material;
|
||||
descriptor = layout->allocateDescriptorSet();
|
||||
for (auto& param : parameters)
|
||||
{
|
||||
param->updateDescriptorSet(descriptor, uniformData.data());
|
||||
}
|
||||
descriptor->writeChanges();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "Material.h"
|
||||
#include "Graphics/Buffer.h"
|
||||
#include "Asset/MaterialAsset.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -8,16 +9,22 @@ class MaterialInstance
|
||||
{
|
||||
public:
|
||||
MaterialInstance();
|
||||
MaterialInstance(uint64 id, Gfx::PGraphics graphics, PMaterial baseMaterial, Gfx::PDescriptorLayout descriptor, Array<OShaderParameter> params, uint32 uniformBinding, uint32 uniformSize);
|
||||
MaterialInstance(uint64 id,
|
||||
Gfx::PGraphics graphics,
|
||||
Map<std::string, OShaderExpression>& expressions,
|
||||
Array<std::string> params,
|
||||
uint32 uniformBinding,
|
||||
uint32 uniformSize);
|
||||
~MaterialInstance();
|
||||
void updateDescriptor();
|
||||
Gfx::PDescriptorSet getDescriptorSet() const;
|
||||
PMaterial getBaseMaterial() const { return baseMaterial; }
|
||||
PMaterial getBaseMaterial() const { return baseMaterial->getMaterial(); }
|
||||
uint64 getId() const { return id; }
|
||||
|
||||
void setBaseMaterial(PMaterialAsset asset);
|
||||
|
||||
void save(ArchiveBuffer& buffer) const;
|
||||
void load(ArchiveBuffer& buffer);
|
||||
void setBaseMaterial(PMaterial material);
|
||||
|
||||
private:
|
||||
Gfx::PGraphics graphics;
|
||||
@@ -25,9 +32,8 @@ private:
|
||||
uint32 uniformBinding;
|
||||
Gfx::OUniformBuffer uniformBuffer;
|
||||
Array<OShaderParameter> parameters;
|
||||
Gfx::PDescriptorLayout layout;
|
||||
Gfx::PDescriptorSet descriptor;
|
||||
PMaterial baseMaterial;
|
||||
PMaterialAsset baseMaterial;
|
||||
uint64 id;
|
||||
};
|
||||
DEFINE_REF(MaterialInstance)
|
||||
|
||||
@@ -31,6 +31,15 @@ void ExpressionOutput::load(ArchiveBuffer& buffer)
|
||||
Serialization::load(buffer, type);
|
||||
}
|
||||
|
||||
ShaderExpression::ShaderExpression()
|
||||
{
|
||||
}
|
||||
|
||||
ShaderExpression::ShaderExpression(std::string key)
|
||||
: key(key)
|
||||
{
|
||||
}
|
||||
|
||||
void ShaderExpression::save(ArchiveBuffer& buffer) const
|
||||
{
|
||||
Serialization::save(buffer, inputs);
|
||||
@@ -46,7 +55,7 @@ void ShaderExpression::load(ArchiveBuffer& buffer)
|
||||
}
|
||||
|
||||
ShaderParameter::ShaderParameter(std::string name, uint32 byteOffset, uint32 binding)
|
||||
: name(name)
|
||||
: ShaderExpression(name)
|
||||
, byteOffset(byteOffset)
|
||||
, binding(binding)
|
||||
{
|
||||
@@ -56,16 +65,16 @@ ShaderParameter::~ShaderParameter()
|
||||
{
|
||||
}
|
||||
|
||||
std::string ShaderParameter::evaluate(Map<int32, std::string>& varState) const
|
||||
std::string ShaderParameter::evaluate(Map<std::string, std::string>& varState) const
|
||||
{
|
||||
varState[key] = name;
|
||||
varState[key] = key;
|
||||
return "";
|
||||
}
|
||||
|
||||
void ShaderParameter::save(ArchiveBuffer& buffer) const
|
||||
{
|
||||
ShaderExpression::save(buffer);
|
||||
Serialization::save(buffer, name);
|
||||
Serialization::save(buffer, key);
|
||||
Serialization::save(buffer, byteOffset);
|
||||
Serialization::save(buffer, binding);
|
||||
}
|
||||
@@ -73,7 +82,7 @@ void ShaderParameter::save(ArchiveBuffer& buffer) const
|
||||
void ShaderParameter::load(ArchiveBuffer& buffer)
|
||||
{
|
||||
ShaderExpression::load(buffer);
|
||||
Serialization::load(buffer, name);
|
||||
Serialization::load(buffer, key);
|
||||
Serialization::load(buffer, byteOffset);
|
||||
Serialization::load(buffer, binding);
|
||||
}
|
||||
@@ -109,7 +118,7 @@ void FloatParameter::updateDescriptorSet(Gfx::PDescriptorSet, uint8* dst)
|
||||
|
||||
void FloatParameter::generateDeclaration(std::ofstream& stream) const
|
||||
{
|
||||
stream << "\tlayout(offset = " << byteOffset << ") float " << name << ";\n";
|
||||
stream << "\tlayout(offset = " << byteOffset << ") float " << key << ";\n";
|
||||
}
|
||||
|
||||
VectorParameter::VectorParameter(std::string name, uint32 byteOffset, uint32 binding)
|
||||
@@ -131,7 +140,7 @@ void VectorParameter::updateDescriptorSet(Gfx::PDescriptorSet, uint8* dst)
|
||||
|
||||
void VectorParameter::generateDeclaration(std::ofstream& stream) const
|
||||
{
|
||||
stream << "\tlayout(offset = " << byteOffset << ") float3 " << name << ";\n";
|
||||
stream << "\tlayout(offset = " << byteOffset << ") float3 " << key << ";\n";
|
||||
}
|
||||
|
||||
void VectorParameter::save(ArchiveBuffer& buffer) const
|
||||
@@ -164,7 +173,7 @@ void TextureParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, ui
|
||||
|
||||
void TextureParameter::generateDeclaration(std::ofstream& stream) const
|
||||
{
|
||||
stream << "\tTexture2D " << name << ";\n";
|
||||
stream << "\tTexture2D " << key << ";\n";
|
||||
}
|
||||
|
||||
void TextureParameter::save(ArchiveBuffer& buffer) const
|
||||
@@ -200,7 +209,7 @@ void SamplerParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, ui
|
||||
|
||||
void SamplerParameter::generateDeclaration(std::ofstream& stream) const
|
||||
{
|
||||
stream << "\tSamplerState " << name << ";\n";
|
||||
stream << "\tSamplerState " << key << ";\n";
|
||||
}
|
||||
|
||||
void SamplerParameter::save(ArchiveBuffer& buffer) const
|
||||
@@ -233,7 +242,7 @@ void CombinedTextureParameter::updateDescriptorSet(Gfx::PDescriptorSet descripto
|
||||
|
||||
void CombinedTextureParameter::generateDeclaration(std::ofstream& stream) const
|
||||
{
|
||||
stream << "\tTexture2D " << name << ";\n";
|
||||
stream << "\tTexture2D " << key << ";\n";
|
||||
}
|
||||
|
||||
void CombinedTextureParameter::save(ArchiveBuffer& buffer) const
|
||||
@@ -267,9 +276,9 @@ ConstantExpression::~ConstantExpression()
|
||||
|
||||
}
|
||||
|
||||
std::string ConstantExpression::evaluate(Map<int32, std::string>& varState) const
|
||||
std::string ConstantExpression::evaluate(Map<std::string, std::string>& varState) const
|
||||
{
|
||||
std::string varName = std::format("const_exp_{}", std::abs(key));
|
||||
std::string varName = std::format("const_exp_{}", key);
|
||||
varState[key] = varName;
|
||||
return std::format("let {} = {};\n", varName, expr);
|
||||
}
|
||||
@@ -296,7 +305,7 @@ AddExpression::~AddExpression()
|
||||
|
||||
}
|
||||
|
||||
std::string AddExpression::evaluate(Map<int32, std::string>& varState) const
|
||||
std::string AddExpression::evaluate(Map<std::string, std::string>& varState) const
|
||||
{
|
||||
std::string varName = std::format("exp_{}", key);
|
||||
varState[key] = varName;
|
||||
@@ -313,7 +322,7 @@ void AddExpression::load(ArchiveBuffer& buffer)
|
||||
ShaderExpression::load(buffer);
|
||||
}
|
||||
|
||||
std::string SubExpression::evaluate(Map<int32, std::string>& varState) const
|
||||
std::string SubExpression::evaluate(Map<std::string, std::string>& varState) const
|
||||
{
|
||||
std::string varName = std::format("exp_{}", key);
|
||||
varState[key] = varName;
|
||||
@@ -330,7 +339,7 @@ void SubExpression::load(ArchiveBuffer& buffer)
|
||||
ShaderExpression::load(buffer);
|
||||
}
|
||||
|
||||
std::string MulExpression::evaluate(Map<int32, std::string>& varState) const
|
||||
std::string MulExpression::evaluate(Map<std::string, std::string>& varState) const
|
||||
{
|
||||
std::string varName = std::format("exp_{}", key);
|
||||
varState[key] = varName;
|
||||
@@ -347,7 +356,7 @@ void MulExpression::load(ArchiveBuffer& buffer)
|
||||
ShaderExpression::load(buffer);
|
||||
}
|
||||
|
||||
std::string SwizzleExpression::evaluate(Map<int32, std::string>& varState) const
|
||||
std::string SwizzleExpression::evaluate(Map<std::string, std::string>& varState) const
|
||||
{
|
||||
std::string varName = std::format("exp_{}", key);
|
||||
std::string swizzle = "";
|
||||
@@ -370,6 +379,7 @@ std::string SwizzleExpression::evaluate(Map<int32, std::string>& varState) const
|
||||
break;
|
||||
case 3:
|
||||
swizzle += "w";
|
||||
break;
|
||||
default:
|
||||
throw std::logic_error("invalid component");
|
||||
}
|
||||
@@ -390,7 +400,7 @@ void SwizzleExpression::load(ArchiveBuffer& buffer)
|
||||
Serialization::load(buffer, comp);
|
||||
}
|
||||
|
||||
std::string SampleExpression::evaluate(Map<int32, std::string>& varState) const
|
||||
std::string SampleExpression::evaluate(Map<std::string, std::string>& varState) const
|
||||
{
|
||||
std::string varName = std::format("exp_{}", key);
|
||||
varState[key] = varName;
|
||||
|
||||
@@ -18,7 +18,7 @@ enum class ExpressionType
|
||||
};
|
||||
struct ExpressionInput
|
||||
{
|
||||
int source;
|
||||
std::string source;
|
||||
ExpressionType type = ExpressionType::UNKNOWN;
|
||||
void save(ArchiveBuffer& buffer) const;
|
||||
void load(ArchiveBuffer& buffer);
|
||||
@@ -35,9 +35,11 @@ struct ShaderExpression
|
||||
{
|
||||
Map<std::string, ExpressionInput> inputs;
|
||||
ExpressionOutput output;
|
||||
int32 key;
|
||||
std::string key;
|
||||
ShaderExpression();
|
||||
ShaderExpression(std::string key);
|
||||
virtual uint64 getIdentifier() const = 0;
|
||||
virtual std::string evaluate(Map<int32, std::string>& varState) const = 0;
|
||||
virtual std::string evaluate(Map<std::string, std::string>& varState) const = 0;
|
||||
virtual void save(ArchiveBuffer& buffer) const;
|
||||
virtual void load(ArchiveBuffer& buffer);
|
||||
};
|
||||
@@ -46,7 +48,6 @@ DEFINE_REF(ShaderExpression)
|
||||
DECLARE_NAME_REF(Gfx, DescriptorSet)
|
||||
struct ShaderParameter : public ShaderExpression
|
||||
{
|
||||
std::string name;
|
||||
uint32 byteOffset;
|
||||
uint32 binding;
|
||||
ShaderParameter() {}
|
||||
@@ -56,7 +57,7 @@ struct ShaderParameter : public ShaderExpression
|
||||
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) = 0;
|
||||
virtual void generateDeclaration(std::ofstream& stream) const = 0;
|
||||
virtual uint64 getIdentifier() const = 0;
|
||||
virtual std::string evaluate(Map<int32, std::string>& varState) const override;
|
||||
virtual std::string evaluate(Map<std::string, std::string>& varState) const override;
|
||||
virtual void save(ArchiveBuffer& buffer) const;
|
||||
virtual void load(ArchiveBuffer& buffer);
|
||||
};
|
||||
@@ -143,7 +144,7 @@ struct ConstantExpression : public ShaderExpression
|
||||
ConstantExpression(std::string expr, ExpressionType type);
|
||||
virtual ~ConstantExpression();
|
||||
virtual uint64 getIdentifier() const { return IDENTIFIER; }
|
||||
virtual std::string evaluate(Map<int32, std::string>& varState) const override;
|
||||
virtual std::string evaluate(Map<std::string, std::string>& varState) const override;
|
||||
virtual void save(ArchiveBuffer& buffer) const override;
|
||||
virtual void load(ArchiveBuffer& buffer) override;
|
||||
};
|
||||
@@ -154,7 +155,7 @@ struct AddExpression : public ShaderExpression
|
||||
AddExpression();
|
||||
virtual ~AddExpression();
|
||||
virtual uint64 getIdentifier() const { return IDENTIFIER; }
|
||||
virtual std::string evaluate(Map<int32, std::string>& varState) const override;
|
||||
virtual std::string evaluate(Map<std::string, std::string>& varState) const override;
|
||||
virtual void save(ArchiveBuffer& buffer) const override;
|
||||
virtual void load(ArchiveBuffer& buffer) override;
|
||||
};
|
||||
@@ -165,7 +166,7 @@ struct SubExpression : public ShaderExpression
|
||||
SubExpression() {}
|
||||
virtual ~SubExpression() {}
|
||||
virtual uint64 getIdentifier() const { return IDENTIFIER; }
|
||||
virtual std::string evaluate(Map<int32, std::string>& varState) const override;
|
||||
virtual std::string evaluate(Map<std::string, std::string>& varState) const override;
|
||||
virtual void save(ArchiveBuffer& buffer) const override;
|
||||
virtual void load(ArchiveBuffer& buffer) override;
|
||||
};
|
||||
@@ -176,7 +177,7 @@ struct MulExpression : public ShaderExpression
|
||||
MulExpression() {}
|
||||
virtual ~MulExpression() {}
|
||||
virtual uint64 getIdentifier() const { return IDENTIFIER; }
|
||||
virtual std::string evaluate(Map<int32, std::string>& varState) const override;
|
||||
virtual std::string evaluate(Map<std::string, std::string>& varState) const override;
|
||||
virtual void save(ArchiveBuffer& buffer) const override;
|
||||
virtual void load(ArchiveBuffer& buffer) override;
|
||||
};
|
||||
@@ -188,7 +189,7 @@ struct SwizzleExpression : public ShaderExpression
|
||||
SwizzleExpression() {}
|
||||
virtual ~SwizzleExpression() {}
|
||||
virtual uint64 getIdentifier() const { return IDENTIFIER; }
|
||||
virtual std::string evaluate(Map<int32, std::string>& varState) const override;
|
||||
virtual std::string evaluate(Map<std::string, std::string>& varState) const override;
|
||||
virtual void save(ArchiveBuffer& buffer) const override;
|
||||
virtual void load(ArchiveBuffer& buffer) override;
|
||||
};
|
||||
@@ -199,7 +200,7 @@ struct SampleExpression : public ShaderExpression
|
||||
SampleExpression() {}
|
||||
virtual ~SampleExpression() {}
|
||||
virtual uint64 getIdentifier() const { return IDENTIFIER; }
|
||||
virtual std::string evaluate(Map<int32, std::string>& varState) const override;
|
||||
virtual std::string evaluate(Map<std::string, std::string>& varState) const override;
|
||||
virtual void save(ArchiveBuffer& buffer) const override;
|
||||
virtual void load(ArchiveBuffer& buffer) override;
|
||||
};
|
||||
@@ -208,7 +209,7 @@ DEFINE_REF(SampleExpression)
|
||||
struct MaterialNode
|
||||
{
|
||||
std::string profile;
|
||||
Map<std::string, OShaderExpression> variables;
|
||||
Map<std::string, std::string> variables;
|
||||
MaterialNode() {}
|
||||
~MaterialNode() {}
|
||||
void save(ArchiveBuffer& buffer) const;
|
||||
|
||||
@@ -53,9 +53,4 @@ struct Rect3D
|
||||
Vector size;
|
||||
Vector offset;
|
||||
};
|
||||
template <typename T>
|
||||
inline constexpr T align(const T ptr, int64_t alignment)
|
||||
{
|
||||
return (T)(((uint64_t)ptr + alignment - 1) & ~(alignment - 1));
|
||||
}
|
||||
} // namespace Seele
|
||||
@@ -41,10 +41,6 @@ Transform::Transform(Quaternion rotation, Vector scale)
|
||||
Transform::~Transform()
|
||||
{
|
||||
}
|
||||
Vector Transform::inverseTransformPosition(const Vector &v) const
|
||||
{
|
||||
return (unrotateVector(rotation, v - Vector(position))) * getSafeScaleReciprocal(scale);
|
||||
}
|
||||
Matrix4 Transform::toMatrix() const
|
||||
{
|
||||
Matrix4 mat;
|
||||
@@ -95,35 +91,6 @@ Matrix4 Transform::toMatrix() const
|
||||
|
||||
return mat;
|
||||
}
|
||||
Vector Transform::getSafeScaleReciprocal(const Vector4 &inScale, float tolerance)
|
||||
{
|
||||
Vector safeReciprocalScale;
|
||||
if (abs(inScale.x) <= tolerance)
|
||||
{
|
||||
safeReciprocalScale.x = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
safeReciprocalScale.x = 1 / inScale.x;
|
||||
}
|
||||
if (abs(inScale.y) <= tolerance)
|
||||
{
|
||||
safeReciprocalScale.y = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
safeReciprocalScale.y = 1 / inScale.y;
|
||||
}
|
||||
if (abs(inScale.z) <= tolerance)
|
||||
{
|
||||
safeReciprocalScale.z = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
safeReciprocalScale.z = 1 / inScale.z;
|
||||
}
|
||||
return safeReciprocalScale;
|
||||
}
|
||||
|
||||
Vector Transform::transformPosition(const Vector &v) const
|
||||
{
|
||||
|
||||
@@ -17,9 +17,7 @@ public:
|
||||
Transform(Vector position, Quaternion rotation, Vector scale);
|
||||
Transform(Quaternion rotation, Vector scale);
|
||||
~Transform();
|
||||
Vector inverseTransformPosition(const Vector &v) const;
|
||||
Matrix4 toMatrix() const;
|
||||
static Vector getSafeScaleReciprocal(const Vector4 &inScale, float tolerance = 0.000000001f);
|
||||
Vector transformPosition(const Vector &v) const;
|
||||
|
||||
Vector getPosition() const;
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include "Serialization/Serialization.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -32,103 +31,8 @@ typedef glm::quat Quaternion;
|
||||
|
||||
Vector parseVector(const char*);
|
||||
|
||||
static inline float square(float x)
|
||||
{
|
||||
return x * x;
|
||||
}
|
||||
|
||||
static inline Vector unrotateVector(Quaternion quaternion, Vector v)
|
||||
{
|
||||
const Vector q(-quaternion.x, -quaternion.y, -quaternion.z);
|
||||
const Vector t = 2.f * glm::cross(q, v);
|
||||
const Vector result = v + (quaternion.w * t) + glm::cross(q, t);
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline bool equalsQuaternion(const Quaternion &right, const Quaternion &left, float tolerance)
|
||||
{
|
||||
return (abs(right.x - left.x) <= tolerance && abs(right.y - left.y) <= tolerance && abs(right.z - left.z) <= tolerance && abs(right.w - left.w) <= tolerance) || (abs(right.x + left.x) <= tolerance && abs(right.y + left.y) <= tolerance && abs(right.z + left.z) <= tolerance && abs(right.w + left.w) <= tolerance);
|
||||
}
|
||||
|
||||
static inline float clampRotatorAxis(float angle)
|
||||
{
|
||||
angle = fmod(angle, 360.f);
|
||||
if (angle < 0.f)
|
||||
{
|
||||
angle += 360.f;
|
||||
}
|
||||
return angle;
|
||||
}
|
||||
static inline float normalizeRotatorAxis(float angle)
|
||||
{
|
||||
angle = clampRotatorAxis(angle);
|
||||
|
||||
if (angle > 180.f)
|
||||
{
|
||||
angle -= 360.f;
|
||||
}
|
||||
return angle;
|
||||
}
|
||||
|
||||
|
||||
static inline Vector toRotator(const Quaternion &other)
|
||||
{
|
||||
const float singularityTest = other.z * other.x - other.w * other.y;
|
||||
const float yawY = 2.f * (other.w * other.z + other.x * other.y);
|
||||
const float yawX = (1.f - 2.f * (square(other.y) + square(other.z)));
|
||||
|
||||
const float SINGULARITY_THRESHOLD = 0.4999995f;
|
||||
constexpr const float RAD_TO_DEG = (180.f) / glm::pi<float>();
|
||||
Vector rotatorFromQuat;
|
||||
|
||||
if (singularityTest < -SINGULARITY_THRESHOLD)
|
||||
{
|
||||
rotatorFromQuat.x = -90.f;
|
||||
rotatorFromQuat.y = atan2(yawY, yawX) * RAD_TO_DEG;
|
||||
rotatorFromQuat.z = normalizeRotatorAxis(-rotatorFromQuat.y - (2.f * atan2(other.x, other.w) * RAD_TO_DEG));
|
||||
}
|
||||
else if (singularityTest > SINGULARITY_THRESHOLD)
|
||||
{
|
||||
rotatorFromQuat.x = 90.f;
|
||||
rotatorFromQuat.y = atan2(yawY, yawX) * RAD_TO_DEG;
|
||||
rotatorFromQuat.z = normalizeRotatorAxis(rotatorFromQuat.y - (2.f * atan2(other.x, other.w) * RAD_TO_DEG));
|
||||
}
|
||||
else
|
||||
{
|
||||
rotatorFromQuat.x = asin(2.f * (singularityTest)) * RAD_TO_DEG;
|
||||
rotatorFromQuat.y = atan2(yawY, yawX) * RAD_TO_DEG;
|
||||
rotatorFromQuat.z = atan2(-2.f * (other.w * other.x + other.y * other.z), (1.f - 2.f * (square(other.x) + square(other.y)))) * RAD_TO_DEG;
|
||||
}
|
||||
return rotatorFromQuat;
|
||||
}
|
||||
void to_json(nlohmann::json& j, const Vector& vec);
|
||||
void from_json(nlohmann::json& j, Vector& vec);
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
static void save(ArchiveBuffer& buffer, const IVector2& vec)
|
||||
{
|
||||
save(buffer, vec.x);
|
||||
save(buffer, vec.y);
|
||||
}
|
||||
static void load(ArchiveBuffer& buffer, IVector2& vec)
|
||||
{
|
||||
save(buffer, vec.x);
|
||||
save(buffer, vec.y);
|
||||
}
|
||||
static void save(ArchiveBuffer& buffer, const Vector& vec)
|
||||
{
|
||||
save(buffer, vec.x);
|
||||
save(buffer, vec.y);
|
||||
save(buffer, vec.z);
|
||||
}
|
||||
static void load(ArchiveBuffer& buffer, Vector& vec)
|
||||
{
|
||||
save(buffer, vec.x);
|
||||
save(buffer, vec.y);
|
||||
save(buffer, vec.z);
|
||||
}
|
||||
} // namespace Serialization
|
||||
} // namespace Seele
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, const Seele::Vector2& vector);
|
||||
|
||||
+104
-76
@@ -26,56 +26,6 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
template <typename T, typename Deleter = std::default_delete<T>>
|
||||
class OwningPtr
|
||||
{
|
||||
public:
|
||||
OwningPtr()
|
||||
: pointer(nullptr)
|
||||
{
|
||||
}
|
||||
OwningPtr(T* ptr)
|
||||
: pointer(ptr)
|
||||
{}
|
||||
template<typename F>
|
||||
OwningPtr(OwningPtr<F>&& other)
|
||||
{
|
||||
pointer = static_cast<T*>(other.pointer);
|
||||
}
|
||||
OwningPtr(const OwningPtr& other) = delete;
|
||||
OwningPtr(OwningPtr&& other)
|
||||
{
|
||||
pointer = other.pointer;
|
||||
other.pointer = nullptr;
|
||||
}
|
||||
OwningPtr& operator=(const OwningPtr& other) = delete;
|
||||
OwningPtr& operator=(OwningPtr&& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
pointer = other.pointer;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
constexpr T* operator->()
|
||||
{
|
||||
return pointer;
|
||||
}
|
||||
constexpr const T* operator->() const
|
||||
{
|
||||
return pointer;
|
||||
}
|
||||
constexpr bool operator==(const OwningPtr& rhs) const noexcept
|
||||
{
|
||||
return pointer == rhs.pointer;
|
||||
}
|
||||
constexpr auto operator<=>(const OwningPtr& rhs) const noexcept
|
||||
{
|
||||
return pointer <=> rhs.pointer;
|
||||
}
|
||||
private:
|
||||
T* pointer;
|
||||
};
|
||||
template <typename T>
|
||||
class RefPtr
|
||||
{
|
||||
@@ -88,44 +38,42 @@ public:
|
||||
: object(nullptr)
|
||||
{
|
||||
}
|
||||
RefPtr(T *ptr)
|
||||
RefPtr(T* ptr)
|
||||
: object(ptr)
|
||||
{
|
||||
}
|
||||
constexpr RefPtr(const RefPtr &other) noexcept
|
||||
constexpr RefPtr(const RefPtr& other) noexcept
|
||||
: object(other.object)
|
||||
{
|
||||
}
|
||||
constexpr RefPtr(RefPtr &&rhs) noexcept
|
||||
constexpr RefPtr(RefPtr&& rhs) noexcept
|
||||
: object(std::move(rhs.object))
|
||||
{
|
||||
rhs.object = nullptr;
|
||||
}
|
||||
template <typename F>
|
||||
constexpr RefPtr(const RefPtr<F> &other)
|
||||
constexpr RefPtr<F> cast()
|
||||
{
|
||||
object = other.cast<T>();
|
||||
}
|
||||
constexpr RefPtr(OwningPtr<T>& owning)
|
||||
{
|
||||
object = owning.getHandle();
|
||||
}
|
||||
constexpr RefPtr(const OwningPtr<T>& owning)
|
||||
{
|
||||
object = owning.getHandle();
|
||||
}
|
||||
template <typename F>
|
||||
constexpr const RefPtr<F> cast() const
|
||||
{
|
||||
T *t = object;
|
||||
F *f = dynamic_cast<F *>(t);
|
||||
T* t = object;
|
||||
F* f = dynamic_cast<F*>(t);
|
||||
if (f == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return RefPtr<F>(f);
|
||||
}
|
||||
constexpr RefPtr &operator=(const RefPtr &other)
|
||||
template <typename F>
|
||||
constexpr const RefPtr<F> cast() const
|
||||
{
|
||||
T* t = object;
|
||||
F* f = dynamic_cast<F*>(t);
|
||||
if (f == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return RefPtr<F>(f);
|
||||
}
|
||||
constexpr RefPtr& operator=(const RefPtr& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
@@ -133,7 +81,7 @@ public:
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
constexpr RefPtr &operator=(RefPtr &&rhs) noexcept
|
||||
constexpr RefPtr& operator=(RefPtr&& rhs) noexcept
|
||||
{
|
||||
if (this != &rhs)
|
||||
{
|
||||
@@ -149,15 +97,25 @@ public:
|
||||
{
|
||||
return object == rhs.object;
|
||||
}
|
||||
constexpr auto operator<=>(const RefPtr &rhs) const noexcept
|
||||
constexpr auto operator<=>(const RefPtr& rhs) const noexcept
|
||||
{
|
||||
return object <=> rhs.object;
|
||||
}
|
||||
constexpr T *operator->()
|
||||
template<typename F>
|
||||
constexpr operator RefPtr<F>()
|
||||
{
|
||||
return RefPtr<F>(static_cast<F*>(object));
|
||||
}
|
||||
template<typename F>
|
||||
constexpr operator RefPtr<F>() const
|
||||
{
|
||||
return RefPtr<F>(static_cast<F*>(object));
|
||||
}
|
||||
constexpr T* operator->()
|
||||
{
|
||||
return object;
|
||||
}
|
||||
constexpr const T *operator->() const
|
||||
constexpr const T* operator->() const
|
||||
{
|
||||
return object;
|
||||
}
|
||||
@@ -172,6 +130,73 @@ public:
|
||||
private:
|
||||
T* object;
|
||||
};
|
||||
template <typename T, typename Deleter = std::default_delete<T>>
|
||||
class OwningPtr
|
||||
{
|
||||
public:
|
||||
OwningPtr()
|
||||
: pointer(nullptr)
|
||||
{
|
||||
}
|
||||
OwningPtr(T* ptr)
|
||||
: pointer(ptr)
|
||||
{}
|
||||
template<typename F>
|
||||
OwningPtr(OwningPtr<F>&& other)
|
||||
{
|
||||
pointer = dynamic_cast<T*>(*other);
|
||||
}
|
||||
OwningPtr(const OwningPtr& other) = delete;
|
||||
OwningPtr(OwningPtr&& other) noexcept
|
||||
{
|
||||
pointer = other.pointer;
|
||||
other.pointer = nullptr;
|
||||
}
|
||||
OwningPtr& operator=(const OwningPtr& other) = delete;
|
||||
OwningPtr& operator=(OwningPtr&& other) noexcept
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
pointer = other.pointer;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
operator RefPtr<T>()
|
||||
{
|
||||
return RefPtr<T>(pointer);
|
||||
}
|
||||
operator RefPtr<T>() const
|
||||
{
|
||||
return RefPtr<T>(pointer);
|
||||
}
|
||||
constexpr T* operator->()
|
||||
{
|
||||
return pointer;
|
||||
}
|
||||
constexpr const T* operator->() const
|
||||
{
|
||||
return pointer;
|
||||
}
|
||||
constexpr T* operator*()
|
||||
{
|
||||
return pointer;
|
||||
}
|
||||
constexpr const T* operator*() const
|
||||
{
|
||||
return pointer;
|
||||
}
|
||||
constexpr bool operator==(const OwningPtr& rhs) const noexcept
|
||||
{
|
||||
return pointer == rhs.pointer;
|
||||
}
|
||||
constexpr auto operator<=>(const OwningPtr& rhs) const noexcept
|
||||
{
|
||||
return pointer <=> rhs.pointer;
|
||||
}
|
||||
private:
|
||||
friend class RefPtr<T>;
|
||||
T* pointer;
|
||||
};
|
||||
template <typename T>
|
||||
class UniquePtr
|
||||
{
|
||||
@@ -197,8 +222,11 @@ public:
|
||||
UniquePtr &operator=(const UniquePtr &rhs) = delete;
|
||||
UniquePtr &operator=(UniquePtr &&rhs)
|
||||
{
|
||||
handle = rhs.handle;
|
||||
rhs.handle = nullptr;
|
||||
if (this != &rhs)
|
||||
{
|
||||
handle = rhs.handle;
|
||||
rhs.handle = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
~UniquePtr()
|
||||
|
||||
@@ -16,7 +16,7 @@ LightEnvironment::LightEnvironment(Gfx::PGraphics graphics)
|
||||
.size = sizeof(LightEnv),
|
||||
.data = (uint8*) &lightEnv,
|
||||
},
|
||||
.bDynamic = true,
|
||||
.dynamic = true,
|
||||
});
|
||||
directionalLights = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData = {
|
||||
@@ -24,7 +24,7 @@ LightEnvironment::LightEnvironment(Gfx::PGraphics graphics)
|
||||
.data = (uint8*)dirs.data(),
|
||||
},
|
||||
.stride = sizeof(Component::DirectionalLight),
|
||||
.bDynamic = true,
|
||||
.dynamic = true,
|
||||
});
|
||||
pointLights = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData = {
|
||||
@@ -32,7 +32,7 @@ LightEnvironment::LightEnvironment(Gfx::PGraphics graphics)
|
||||
.data = (uint8*)dirs.data(),
|
||||
},
|
||||
.stride = sizeof(Component::PointLight),
|
||||
.bDynamic = true,
|
||||
.dynamic = true,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -78,3 +78,13 @@ void LightEnvironment::commit()
|
||||
set->updateBuffer(1, directionalLights);
|
||||
set->updateBuffer(2, pointLights);
|
||||
}
|
||||
|
||||
const Gfx::PDescriptorLayout Seele::LightEnvironment::getDescriptorLayout() const
|
||||
{
|
||||
return layout;
|
||||
}
|
||||
|
||||
Gfx::PDescriptorSet Seele::LightEnvironment::getDescriptorSet()
|
||||
{
|
||||
return set;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ public:
|
||||
void addDirectionalLight(Component::DirectionalLight dirLight);
|
||||
void addPointLight(Component::PointLight pointLight);
|
||||
void commit();
|
||||
const Gfx::PDescriptorLayout getDescriptorLayout() const;
|
||||
Gfx::PDescriptorSet getDescriptorSet();
|
||||
private:
|
||||
#define MAX_DIRECTIONAL_LIGHTS 4
|
||||
#define MAX_POINT_LIGHTS 256
|
||||
@@ -29,7 +31,7 @@ private:
|
||||
Array<Component::DirectionalLight> dirs;
|
||||
Array<Component::PointLight> points;
|
||||
Gfx::ODescriptorLayout layout;
|
||||
Gfx::ODescriptorSet set;
|
||||
Gfx::PDescriptorSet set;
|
||||
Gfx::PGraphics graphics;
|
||||
};
|
||||
DEFINE_REF(LightEnvironment)
|
||||
|
||||
@@ -25,6 +25,7 @@ Scene::~Scene()
|
||||
|
||||
void Scene::update(float deltaTime)
|
||||
{
|
||||
lightEnv->reset();
|
||||
physics.update(deltaTime);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "ArchiveBuffer.h"
|
||||
#include "Math/Vector.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -25,6 +26,38 @@ namespace Serialization
|
||||
{
|
||||
buffer.readBytes(&type, sizeof(type));
|
||||
}
|
||||
static void save(ArchiveBuffer& buffer, const IVector2& vec)
|
||||
{
|
||||
save(buffer, vec.x);
|
||||
save(buffer, vec.y);
|
||||
}
|
||||
static void load(ArchiveBuffer& buffer, IVector2& vec)
|
||||
{
|
||||
save(buffer, vec.x);
|
||||
save(buffer, vec.y);
|
||||
}
|
||||
static void save(ArchiveBuffer& buffer, const Vector2& vec)
|
||||
{
|
||||
save(buffer, vec.x);
|
||||
save(buffer, vec.y);
|
||||
}
|
||||
static void load(ArchiveBuffer& buffer, Vector2& vec)
|
||||
{
|
||||
save(buffer, vec.x);
|
||||
save(buffer, vec.y);
|
||||
}
|
||||
static void save(ArchiveBuffer& buffer, const Vector& vec)
|
||||
{
|
||||
save(buffer, vec.x);
|
||||
save(buffer, vec.y);
|
||||
save(buffer, vec.z);
|
||||
}
|
||||
static void load(ArchiveBuffer& buffer, Vector& vec)
|
||||
{
|
||||
save(buffer, vec.x);
|
||||
save(buffer, vec.y);
|
||||
save(buffer, vec.z);
|
||||
}
|
||||
template<enumeration T>
|
||||
static void save(ArchiveBuffer& buffer, const T& type)
|
||||
{
|
||||
@@ -92,7 +125,7 @@ namespace Serialization
|
||||
{
|
||||
uint64 length = type.size();
|
||||
buffer.writeBytes(&length, sizeof(uint64));
|
||||
for (const auto& x : type)
|
||||
for (const T& x : type)
|
||||
{
|
||||
save(buffer, x);
|
||||
}
|
||||
@@ -102,10 +135,12 @@ namespace Serialization
|
||||
{
|
||||
uint64 length = 0;
|
||||
buffer.readBytes(&length, sizeof(uint64));
|
||||
type.resize(length);
|
||||
for (auto& x : type)
|
||||
type.reserve(length);
|
||||
for (uint32 i = 0; i < length; ++i)
|
||||
{
|
||||
load(buffer, x);
|
||||
T t = T();
|
||||
load(buffer, t);
|
||||
type.add(std::move(t));
|
||||
}
|
||||
}
|
||||
} // namespace Serialization
|
||||
|
||||
@@ -11,10 +11,10 @@ GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate
|
||||
: View(graphics, window, createInfo, "Game")
|
||||
, gameInterface(dllPath)
|
||||
, renderGraph(RenderGraphBuilder::build(
|
||||
DepthPrepass(graphics, scene),
|
||||
LightCullingPass(graphics, scene),
|
||||
BasePass(graphics, scene),
|
||||
SkyboxRenderPass(graphics, scene)
|
||||
std::move(DepthPrepass(graphics, scene)),
|
||||
std::move(LightCullingPass(graphics, scene)),
|
||||
std::move(BasePass(graphics, scene)),
|
||||
std::move(SkyboxRenderPass(graphics, scene))
|
||||
))
|
||||
{
|
||||
reloadGame();
|
||||
@@ -43,6 +43,7 @@ void GameView::update()
|
||||
{
|
||||
vd->createDescriptors();
|
||||
}
|
||||
scene->getLightEnvironment()->commit();
|
||||
auto endTime = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<float> duration = (endTime - startTime);
|
||||
updateTime = duration.count();
|
||||
|
||||
@@ -32,7 +32,7 @@ private:
|
||||
> renderGraph;
|
||||
|
||||
PEntity camera;
|
||||
PScene scene;
|
||||
OScene scene;
|
||||
PSystemGraph systemGraph;
|
||||
dp::thread_pool<> threadPool;
|
||||
float updateTime = 0;
|
||||
|
||||
@@ -22,7 +22,7 @@ PWindow WindowManager::addWindow(Gfx::PGraphics graphics, const WindowCreateInfo
|
||||
|
||||
void WindowManager::notifyWindowClosed(PWindow window)
|
||||
{
|
||||
windows.remove(windows.find([window] (OWindow w) { return window == w; }));
|
||||
windows.remove(windows.find([window] (const OWindow& w) { return window == w; }));
|
||||
if(windows.empty())
|
||||
{
|
||||
exit(0);
|
||||
|
||||
Reference in New Issue
Block a user