Implementing basic asset serialization

This commit is contained in:
Dynamitos
2023-02-13 14:56:13 +01:00
parent 9e1e4076f0
commit 48fa098546
82 changed files with 1834 additions and 423 deletions
+48 -4
View File
@@ -40,9 +40,53 @@ Gfx::PDescriptorSet Material::createDescriptorSet()
return descriptorSet;
}
PMaterialInstance Material::instantiate()
void Material::save(ArchiveBuffer& buffer) const
{
return new MaterialInstance(graphics, this);
MaterialInterface::save(buffer);
Serialization::save(buffer,materialName);
Serialization::save(buffer, layout->getSetIndex());
const auto& bindings = layout->getBindings();
Serialization::save(buffer, bindings.size());
for (const auto& binding : bindings)
{
Serialization::save(buffer, binding.binding);
Serialization::save(buffer, binding.bindingFlags);
Serialization::save(buffer, binding.descriptorCount);
Serialization::save(buffer, binding.descriptorType);
Serialization::save(buffer, binding.shaderStages);
}
}
void Material::load(ArchiveBuffer& buffer)
{
graphics = buffer.getGraphics();
MaterialInterface::load(buffer);
Serialization::load(buffer, materialName);
uint32 setIndex;
Serialization::load(buffer, setIndex);
uint64 numBindings;
Serialization::load(buffer, numBindings);
layout = graphics->createDescriptorLayout();
for (uint64 i = 0; i < numBindings; ++i)
{
uint32 binding;
Serialization::load(buffer, binding);
Gfx::SeDescriptorBindingFlags bindingFlags;
Serialization::load(buffer, bindingFlags);
uint32 descriptorCount;
Serialization::load(buffer, descriptorCount);
Gfx::SeDescriptorType descriptorType;
Serialization::load(buffer, descriptorType);
Gfx::SeShaderStageFlags shaderStages;
Serialization::load(buffer, shaderStages);
layout->addDescriptorBinding(binding, descriptorType, descriptorCount, bindingFlags, shaderStages);
}
layout->create();
}
const Gfx::ShaderCollection* Material::getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const
@@ -50,8 +94,8 @@ const Gfx::ShaderCollection* Material::getShaders(Gfx::RenderPassType renderPass
Gfx::ShaderPermutation permutation;
permutation.passType = renderPass;
std::string vertexInputName = vertexInput->getName();
std::memcpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName));
std::memcpy(permutation.vertexInputName, vertexInputName.c_str(), sizeof(permutation.vertexInputName));
std::strncpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName));
std::strncpy(permutation.vertexInputName, vertexInputName.c_str(), sizeof(permutation.vertexInputName));
return shaderMap.findShaders(Gfx::PermutationId(permutation));
}
+4 -1
View File
@@ -7,13 +7,15 @@ DECLARE_REF(MaterialInstance)
class Material : public MaterialInterface
{
public:
Material() {}
Material(Gfx::PGraphics graphics, Array<PShaderParameter> parameter, Gfx::PDescriptorLayout layout, uint32 uniformDataSize, uint32 uniformBinding, std::string materialName);
virtual ~Material();
virtual Gfx::PDescriptorSet createDescriptorSet();
virtual Gfx::PDescriptorLayout getDescriptorLayout() const { return layout; }
virtual const std::string& getName() { return materialName; }
PMaterialInstance instantiate();
virtual void save(ArchiveBuffer& buffer) const;
virtual void load(ArchiveBuffer& buffer);
virtual const Gfx::ShaderCollection* getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const;
virtual Gfx::ShaderCollection& createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput);
@@ -29,4 +31,5 @@ private:
friend class MaterialInstance;
};
DEFINE_REF(Material)
} // namespace Seele
+41 -2
View File
@@ -27,9 +27,10 @@ MaterialInterface::~MaterialInterface()
{
}
PShaderParameter MaterialInterface::getParameter(const std::string& name)
{
for (auto param : parameters)
for (const auto& param : parameters)
{
if(param->name.compare(name) == 0)
{
@@ -37,4 +38,42 @@ PShaderParameter MaterialInterface::getParameter(const std::string& name)
}
}
return nullptr;
}
}
void MaterialInterface::save(ArchiveBuffer& buffer) const
{
Serialization::save(buffer, uniformDataSize);
Serialization::save(buffer, uniformBinding);
uint64 length = parameters.size();
Serialization::save(buffer, length);
for (const auto& param : parameters)
{
Serialization::save(buffer, param);
}
}
void MaterialInterface::load(ArchiveBuffer& buffer)
{
graphics = buffer.getGraphics();
Serialization::load(buffer, uniformDataSize);
Serialization::load(buffer, uniformBinding);
if (uniformDataSize != 0)
{
uniformData.resize(uniformDataSize);
UniformBufferCreateInfo uniformInitializer = {
.resourceData = {
.size = uniformDataSize,
.data = nullptr,
}
};
uniformBuffer = graphics->createUniformBuffer(uniformInitializer);
}
uint64 length;
Serialization::load(buffer, length);
parameters.resize(length);
for (auto& param : parameters)
{
Serialization::load(buffer, param);
}
}
+4
View File
@@ -9,12 +9,16 @@ DECLARE_NAME_REF(Gfx, UniformBuffer)
class MaterialInterface
{
public:
MaterialInterface() {}
MaterialInterface(Gfx::PGraphics graphics, Array<PShaderParameter> parameter, uint32 uniformDataSize, uint32 uniformBinding);
virtual ~MaterialInterface();
PShaderParameter getParameter(const std::string& name);
virtual Gfx::PDescriptorSet createDescriptorSet() = 0;
virtual Gfx::PDescriptorLayout getDescriptorLayout() const = 0;
virtual void save(ArchiveBuffer& buffer) const;
virtual void load(ArchiveBuffer& buffer);
// The name of the generated material shader, opposed to the name of the .asset file
virtual const std::string& getName() = 0;
virtual const Gfx::ShaderCollection* getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const = 0;
+118
View File
@@ -1,6 +1,8 @@
#include "ShaderExpression.h"
#include "Graphics/GraphicsResources.h"
#include "Asset/TextureAsset.h"
#include "Asset/AssetRegistry.h"
#include "Graphics/Graphics.h"
using namespace Seele;
@@ -15,8 +17,23 @@ ShaderParameter::~ShaderParameter()
{
}
void ShaderParameter::save(ArchiveBuffer& buffer) const
{
Serialization::save(buffer, name);
Serialization::save(buffer, byteOffset);
Serialization::save(buffer, binding);
}
void ShaderParameter::load(ArchiveBuffer& buffer)
{
Serialization::load(buffer, name);
Serialization::load(buffer, byteOffset);
Serialization::load(buffer, binding);
}
FloatParameter::FloatParameter(std::string name, uint32 byteOffset, uint32 binding)
: ShaderParameter(name, byteOffset, binding)
, data(0)
{
}
@@ -24,6 +41,18 @@ FloatParameter::~FloatParameter()
{
}
void FloatParameter::save(ArchiveBuffer& buffer) const
{
ShaderParameter::save(buffer);
Serialization::save(buffer, data);
}
void FloatParameter::load(ArchiveBuffer& buffer)
{
ShaderParameter::load(buffer);
Serialization::load(buffer, data);
}
void FloatParameter::updateDescriptorSet(Gfx::PDescriptorSet, uint8* dst)
{
std::memcpy(dst + byteOffset, &data, sizeof(float));
@@ -31,6 +60,7 @@ void FloatParameter::updateDescriptorSet(Gfx::PDescriptorSet, uint8* dst)
VectorParameter::VectorParameter(std::string name, uint32 byteOffset, uint32 binding)
: ShaderParameter(name, byteOffset, binding)
, data()
{
}
@@ -38,11 +68,24 @@ VectorParameter::~VectorParameter()
{
}
void VectorParameter::updateDescriptorSet(Gfx::PDescriptorSet, uint8* dst)
{
std::memcpy(dst + byteOffset, &data, sizeof(Vector));
}
void VectorParameter::save(ArchiveBuffer& buffer) const
{
ShaderParameter::save(buffer);
Serialization::save(buffer, data);
}
void VectorParameter::load(ArchiveBuffer& buffer)
{
ShaderParameter::load(buffer);
Serialization::load(buffer, data);
}
TextureParameter::TextureParameter(std::string name, uint32 byteOffset, uint32 binding)
: ShaderParameter(name, byteOffset, binding)
{
@@ -57,6 +100,20 @@ void TextureParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, ui
descriptorSet->updateTexture(binding, data->getTexture());
}
void TextureParameter::save(ArchiveBuffer& buffer) const
{
ShaderParameter::save(buffer);
Serialization::save(buffer, data->getAssetIdentifier());
}
void TextureParameter::load(ArchiveBuffer& buffer)
{
ShaderParameter::load(buffer);
std::string filename;
Serialization::load(buffer, filename);
data = AssetRegistry::findTexture(filename);
}
SamplerParameter::SamplerParameter(std::string name, uint32 byteOffset, uint32 binding)
: ShaderParameter(name, byteOffset, binding)
{
@@ -72,6 +129,18 @@ void SamplerParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, ui
descriptorSet->updateSampler(binding, data);
}
void SamplerParameter::save(ArchiveBuffer& buffer) const
{
ShaderParameter::save(buffer);
}
void SamplerParameter::load(ArchiveBuffer& buffer)
{
ShaderParameter::load(buffer);
data = buffer.getGraphics()->createSamplerState({});
}
CombinedTextureParameter::CombinedTextureParameter(std::string name, uint32 byteOffset, uint32 binding)
: ShaderParameter(name, byteOffset, binding)
{
@@ -82,7 +151,56 @@ CombinedTextureParameter::~CombinedTextureParameter()
}
void CombinedTextureParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8*)
{
descriptorSet->updateTexture(binding, data->getTexture(), sampler);
}
void CombinedTextureParameter::save(ArchiveBuffer& buffer) const
{
ShaderParameter::save(buffer);
Serialization::save(buffer, data->getAssetIdentifier());
}
void CombinedTextureParameter::load(ArchiveBuffer& buffer)
{
ShaderParameter::load(buffer);
std::string filename;
Serialization::load(buffer, filename);
data = AssetRegistry::findTexture(filename);
sampler = buffer.getGraphics()->createSamplerState({});
}
void Serialization::save(ArchiveBuffer& buffer, const PShaderParameter& parameter)
{
Serialization::save(buffer, parameter->getIdentifier());
parameter->save(buffer);
}
void Serialization::load(ArchiveBuffer& buffer, PShaderParameter& parameter)
{
uint64 identifier = 0;
Serialization::load(buffer, identifier);
switch (identifier)
{
case FloatParameter::IDENTIFIER:
parameter = new FloatParameter();
break;
case VectorParameter::IDENTIFIER:
parameter = new VectorParameter();
break;
case TextureParameter::IDENTIFIER:
parameter = new TextureParameter();
break;
case SamplerParameter::IDENTIFIER:
parameter = new SamplerParameter();
break;
case CombinedTextureParameter::IDENTIFIER:
parameter = new CombinedTextureParameter();
break;
default:
throw std::runtime_error("Unknown Identifier");
}
parameter->load(buffer);
}
+36 -1
View File
@@ -1,5 +1,7 @@
#pragma once
#include "MinimalEngine.h"
#include "Math/Math.h"
#include "Asset/TextureAsset.h"
namespace Seele
{
@@ -20,53 +22,86 @@ struct ShaderParameter : public ShaderExpression
std::string name;
uint32 byteOffset;
uint32 binding;
ShaderParameter() {}
ShaderParameter(std::string name, uint32 byteOffset, uint32 binding);
virtual ~ShaderParameter();
// update a descriptorset, in case of a uniform buffer, copy the data to the dst + byteOffset
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) = 0;
virtual uint64 getIdentifier() const = 0;
virtual void save(ArchiveBuffer& buffer) const;
virtual void load(ArchiveBuffer& buffer);
};
DEFINE_REF(ShaderParameter)
struct FloatParameter : public ShaderParameter
{
static constexpr uint64 IDENTIFIER = 0x01;
float data;
FloatParameter() {}
FloatParameter(std::string name, uint32 byteOffset, uint32 binding);
virtual ~FloatParameter();
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
virtual uint64 getIdentifier() const override { return IDENTIFIER; }
virtual void save(ArchiveBuffer& buffer) const override;
virtual void load(ArchiveBuffer& buffer) override;
};
DEFINE_REF(FloatParameter)
struct VectorParameter : public ShaderParameter
{
static constexpr uint64 IDENTIFIER = 0x02;
Vector data;
VectorParameter() {}
VectorParameter(std::string name, uint32 byteOffset, uint32 binding);
virtual ~VectorParameter();
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
virtual uint64 getIdentifier() const override { return IDENTIFIER; }
virtual void save(ArchiveBuffer& buffer) const override;
virtual void load(ArchiveBuffer& buffer) override;
};
DEFINE_REF(VectorParameter)
DECLARE_REF(TextureAsset)
struct TextureParameter : public ShaderParameter
{
static constexpr uint64 IDENTIFIER = 0x04;
PTextureAsset data;
TextureParameter() {}
TextureParameter(std::string name, uint32 byteOffset, uint32 binding);
virtual ~TextureParameter();
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
virtual uint64 getIdentifier() const override { return IDENTIFIER; }
virtual void save(ArchiveBuffer& buffer) const override;
virtual void load(ArchiveBuffer& buffer) override;
};
DEFINE_REF(TextureParameter)
DECLARE_NAME_REF(Gfx, SamplerState)
struct SamplerParameter : public ShaderParameter
{
static constexpr uint64 IDENTIFIER = 0x08;
Gfx::PSamplerState data;
SamplerParameter() {}
SamplerParameter(std::string name, uint32 byteOffset, uint32 binding);
virtual ~SamplerParameter();
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
virtual uint64 getIdentifier() const override { return IDENTIFIER; }
virtual void save(ArchiveBuffer& buffer) const override;
virtual void load(ArchiveBuffer& buffer) override;
};
DEFINE_REF(SamplerParameter)
struct CombinedTextureParameter : public ShaderParameter
{
static constexpr uint64 IDENTIFIER = 0x10;
PTextureAsset data;
Gfx::PSamplerState sampler;
CombinedTextureParameter() {}
CombinedTextureParameter(std::string name, uint32 byteOffset, uint32 binding);
virtual ~CombinedTextureParameter();
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
virtual uint64 getIdentifier() const override { return IDENTIFIER; }
virtual void save(ArchiveBuffer& buffer) const override;
virtual void load(ArchiveBuffer& buffer) override;
};
DEFINE_REF(CombinedTextureParameter)
namespace Serialization
{
void save(ArchiveBuffer& buffer, const PShaderParameter& parameter);
void load(ArchiveBuffer& buffer, PShaderParameter& parameter);
} // namespace Serialization
} // namespace Seele