Formatted EVERYTHING
This commit is contained in:
@@ -3,38 +3,23 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
Actor::Actor(PScene scene)
|
||||
: Entity(scene)
|
||||
{
|
||||
attachComponent<Component::Transform>();
|
||||
}
|
||||
Actor::Actor(PScene scene) : Entity(scene) { attachComponent<Component::Transform>(); }
|
||||
|
||||
Actor::~Actor()
|
||||
{
|
||||
Actor::~Actor() {}
|
||||
|
||||
}
|
||||
|
||||
void Actor::setParent(PActor newParent)
|
||||
{
|
||||
if(parent != nullptr)
|
||||
{
|
||||
void Actor::setParent(PActor newParent) {
|
||||
if (parent != nullptr) {
|
||||
parent->removeChild(this);
|
||||
}
|
||||
parent = newParent;
|
||||
}
|
||||
void Actor::addChild(PActor child)
|
||||
{
|
||||
void Actor::addChild(PActor child) {
|
||||
children.add(child);
|
||||
child->setParent(this);
|
||||
}
|
||||
void Actor::removeChild(PActor child)
|
||||
{
|
||||
void Actor::removeChild(PActor child) {
|
||||
children.remove(children.find(child), false);
|
||||
child->setParent(nullptr);
|
||||
}
|
||||
|
||||
Component::Transform& Actor::getTransform()
|
||||
{
|
||||
return accessComponent<Component::Transform>();
|
||||
}
|
||||
|
||||
Component::Transform& Actor::getTransform() { return accessComponent<Component::Transform>(); }
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
#pragma once
|
||||
#include "Entity.h"
|
||||
#include "Component/Transform.h"
|
||||
#include "Entity.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
DECLARE_REF(Actor)
|
||||
// Actors are entities that are part of the scene hierarchy
|
||||
// In order for that hierarchy to make sense it requires at least a transform component
|
||||
class Actor : public Entity
|
||||
{
|
||||
public:
|
||||
class Actor : public Entity {
|
||||
public:
|
||||
Actor(PScene scene);
|
||||
virtual ~Actor();
|
||||
|
||||
@@ -17,11 +16,11 @@ public:
|
||||
void addChild(PActor child);
|
||||
void removeChild(PActor child);
|
||||
Array<PActor> getChildren();
|
||||
|
||||
|
||||
Component::Transform& getTransform();
|
||||
|
||||
protected:
|
||||
//Component::Transform& getTransform();
|
||||
protected:
|
||||
// Component::Transform& getTransform();
|
||||
void setParent(PActor parent);
|
||||
PActor parent;
|
||||
Array<PActor> children;
|
||||
|
||||
@@ -3,23 +3,13 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
CameraActor::CameraActor(PScene scene)
|
||||
: Actor(scene)
|
||||
{
|
||||
CameraActor::CameraActor(PScene scene) : Actor(scene) {
|
||||
attachComponent<Component::Camera>();
|
||||
accessComponent<Component::Transform>().setPosition(Vector(10, 5, 14));
|
||||
}
|
||||
|
||||
CameraActor::~CameraActor()
|
||||
{
|
||||
}
|
||||
CameraActor::~CameraActor() {}
|
||||
|
||||
Component::Camera& CameraActor::getCameraComponent()
|
||||
{
|
||||
return accessComponent<Component::Camera>();
|
||||
}
|
||||
Component::Camera& CameraActor::getCameraComponent() { return accessComponent<Component::Camera>(); }
|
||||
|
||||
const Component::Camera& CameraActor::getCameraComponent() const
|
||||
{
|
||||
return accessComponent<Component::Camera>();
|
||||
}
|
||||
const Component::Camera& CameraActor::getCameraComponent() const { return accessComponent<Component::Camera>(); }
|
||||
@@ -2,16 +2,15 @@
|
||||
#include "Actor.h"
|
||||
#include "Component/Camera.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class CameraActor : public Actor
|
||||
{
|
||||
public:
|
||||
namespace Seele {
|
||||
class CameraActor : public Actor {
|
||||
public:
|
||||
CameraActor(PScene scene);
|
||||
virtual ~CameraActor();
|
||||
Component::Camera& getCameraComponent();
|
||||
const Component::Camera& getCameraComponent() const;
|
||||
private:
|
||||
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(CameraActor)
|
||||
} // namespace Seele
|
||||
|
||||
@@ -2,29 +2,18 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
DirectionalLightActor::DirectionalLightActor(PScene scene)
|
||||
: Actor(scene)
|
||||
{
|
||||
attachComponent<Component::DirectionalLight>();
|
||||
}
|
||||
DirectionalLightActor::DirectionalLightActor(PScene scene) : Actor(scene) { attachComponent<Component::DirectionalLight>(); }
|
||||
|
||||
DirectionalLightActor::DirectionalLightActor(PScene scene, Vector color, Vector direction)
|
||||
: Actor(scene)
|
||||
{
|
||||
DirectionalLightActor::DirectionalLightActor(PScene scene, Vector color, Vector direction) : Actor(scene) {
|
||||
attachComponent<Component::DirectionalLight>(Vector4(color, 0), Vector4(direction, 0));
|
||||
}
|
||||
|
||||
DirectionalLightActor::~DirectionalLightActor()
|
||||
{
|
||||
|
||||
}
|
||||
DirectionalLightActor::~DirectionalLightActor() {}
|
||||
|
||||
Component::DirectionalLight& DirectionalLightActor::getDirectionalLightComponent()
|
||||
{
|
||||
Component::DirectionalLight& DirectionalLightActor::getDirectionalLightComponent() {
|
||||
return accessComponent<Component::DirectionalLight>();
|
||||
}
|
||||
|
||||
const Component::DirectionalLight& DirectionalLightActor::getDirectionalLightComponent() const
|
||||
{
|
||||
const Component::DirectionalLight& DirectionalLightActor::getDirectionalLightComponent() const {
|
||||
return accessComponent<Component::DirectionalLight>();
|
||||
}
|
||||
@@ -2,17 +2,16 @@
|
||||
#include "Actor.h"
|
||||
#include "Component/DirectionalLight.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class DirectionalLightActor : public Actor
|
||||
{
|
||||
public:
|
||||
namespace Seele {
|
||||
class DirectionalLightActor : public Actor {
|
||||
public:
|
||||
DirectionalLightActor(PScene scene);
|
||||
DirectionalLightActor(PScene scene, Vector color, Vector direction);
|
||||
virtual ~DirectionalLightActor();
|
||||
Component::DirectionalLight& getDirectionalLightComponent();
|
||||
const Component::DirectionalLight& getDirectionalLightComponent() const;
|
||||
private:
|
||||
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(DirectionalLightActor)
|
||||
} // namespace Seele
|
||||
|
||||
@@ -2,14 +2,6 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
Entity::Entity(PScene scene)
|
||||
: scene(scene)
|
||||
, identifier(scene->createEntity())
|
||||
{
|
||||
}
|
||||
Entity::Entity(PScene scene) : scene(scene), identifier(scene->createEntity()) {}
|
||||
|
||||
|
||||
Entity::~Entity()
|
||||
{
|
||||
scene->destroyEntity(identifier);
|
||||
}
|
||||
Entity::~Entity() { scene->destroyEntity(identifier); }
|
||||
+10
-20
@@ -1,33 +1,23 @@
|
||||
#pragma once
|
||||
#include <entt/entt.hpp>
|
||||
#include "MinimalEngine.h"
|
||||
#include "Scene/Scene.h"
|
||||
namespace Seele
|
||||
{
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
namespace Seele {
|
||||
// An entity describes a part of a scene
|
||||
// It is just a wrapper the ID of a registry
|
||||
class Entity
|
||||
{
|
||||
public:
|
||||
class Entity {
|
||||
public:
|
||||
Entity(PScene scene);
|
||||
virtual ~Entity();
|
||||
|
||||
template<typename Component, typename... Args>
|
||||
Component& attachComponent(Args&&... args)
|
||||
{
|
||||
template <typename Component, typename... Args> Component& attachComponent(Args&&... args) {
|
||||
return scene->attachComponent<Component>(identifier, std::forward<Args>(args)...);
|
||||
}
|
||||
template<typename Component>
|
||||
Component& accessComponent()
|
||||
{
|
||||
return scene->accessComponent<Component>(identifier);
|
||||
}
|
||||
template<typename Component>
|
||||
const Component& accessComponent() const
|
||||
{
|
||||
return scene->accessComponent<Component>(identifier);
|
||||
}
|
||||
protected:
|
||||
template <typename Component> Component& accessComponent() { return scene->accessComponent<Component>(identifier); }
|
||||
template <typename Component> const Component& accessComponent() const { return scene->accessComponent<Component>(identifier); }
|
||||
|
||||
protected:
|
||||
PScene scene;
|
||||
entt::entity identifier;
|
||||
};
|
||||
|
||||
@@ -2,29 +2,14 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
PointLightActor::PointLightActor(PScene scene)
|
||||
: Actor(scene)
|
||||
{
|
||||
attachComponent<Component::PointLight>();
|
||||
}
|
||||
PointLightActor::PointLightActor(PScene scene) : Actor(scene) { attachComponent<Component::PointLight>(); }
|
||||
|
||||
PointLightActor::PointLightActor(PScene scene, Vector position, Vector color, float attenuation)
|
||||
: Actor(scene)
|
||||
{
|
||||
PointLightActor::PointLightActor(PScene scene, Vector position, Vector color, float attenuation) : Actor(scene) {
|
||||
attachComponent<Component::PointLight>(Vector4(position, 1), Vector4(color, attenuation));
|
||||
}
|
||||
|
||||
PointLightActor::~PointLightActor()
|
||||
{
|
||||
|
||||
}
|
||||
PointLightActor::~PointLightActor() {}
|
||||
|
||||
Component::PointLight& PointLightActor::getPointLightComponent()
|
||||
{
|
||||
return accessComponent<Component::PointLight>();
|
||||
}
|
||||
Component::PointLight& PointLightActor::getPointLightComponent() { return accessComponent<Component::PointLight>(); }
|
||||
|
||||
const Component::PointLight& PointLightActor::getPointLightComponent() const
|
||||
{
|
||||
return accessComponent<Component::PointLight>();
|
||||
}
|
||||
const Component::PointLight& PointLightActor::getPointLightComponent() const { return accessComponent<Component::PointLight>(); }
|
||||
@@ -2,17 +2,16 @@
|
||||
#include "Actor.h"
|
||||
#include "Component/PointLight.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class PointLightActor : public Actor
|
||||
{
|
||||
public:
|
||||
namespace Seele {
|
||||
class PointLightActor : public Actor {
|
||||
public:
|
||||
PointLightActor(PScene scene);
|
||||
PointLightActor(PScene scene, Vector position, Vector color, float attenuation);
|
||||
virtual ~PointLightActor();
|
||||
Component::PointLight& getPointLightComponent();
|
||||
const Component::PointLight& getPointLightComponent() const;
|
||||
private:
|
||||
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(PointLightActor)
|
||||
} // namespace Seele
|
||||
|
||||
@@ -2,22 +2,10 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
StaticMeshActor::StaticMeshActor(PScene scene, PMeshAsset mesh)
|
||||
: Actor(scene)
|
||||
{
|
||||
attachComponent<Component::Mesh>(mesh);
|
||||
}
|
||||
StaticMeshActor::StaticMeshActor(PScene scene, PMeshAsset mesh) : Actor(scene) { attachComponent<Component::Mesh>(mesh); }
|
||||
|
||||
Seele::StaticMeshActor::~StaticMeshActor()
|
||||
{
|
||||
}
|
||||
Seele::StaticMeshActor::~StaticMeshActor() {}
|
||||
|
||||
Component::Mesh &Seele::StaticMeshActor::getMesh()
|
||||
{
|
||||
return accessComponent<Component::Mesh>();
|
||||
}
|
||||
Component::Mesh& Seele::StaticMeshActor::getMesh() { return accessComponent<Component::Mesh>(); }
|
||||
|
||||
const Component::Mesh &Seele::StaticMeshActor::getMesh() const
|
||||
{
|
||||
return accessComponent<Component::Mesh>();
|
||||
}
|
||||
const Component::Mesh& Seele::StaticMeshActor::getMesh() const { return accessComponent<Component::Mesh>(); }
|
||||
|
||||
@@ -2,16 +2,15 @@
|
||||
#include "Actor.h"
|
||||
#include "Component/Mesh.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class StaticMeshActor : public Actor
|
||||
{
|
||||
public:
|
||||
namespace Seele {
|
||||
class StaticMeshActor : public Actor {
|
||||
public:
|
||||
StaticMeshActor(PScene scene, PMeshAsset mesh);
|
||||
virtual ~StaticMeshActor();
|
||||
Component::Mesh& getMesh();
|
||||
const Component::Mesh& getMesh() const;
|
||||
private:
|
||||
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(StaticMeshActor)
|
||||
} // namespace Seele
|
||||
|
||||
@@ -4,44 +4,19 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
Asset::Asset()
|
||||
: folderPath("")
|
||||
, name("")
|
||||
, status(Status::Uninitialized)
|
||||
, byteSize(0)
|
||||
{
|
||||
}
|
||||
Asset::Asset(std::string_view _folderPath, std::string_view _name)
|
||||
: folderPath(_folderPath)
|
||||
, name(_name)
|
||||
, status(Status::Uninitialized)
|
||||
{
|
||||
if (folderPath.empty())
|
||||
{
|
||||
Asset::Asset() : folderPath(""), name(""), status(Status::Uninitialized), byteSize(0) {}
|
||||
Asset::Asset(std::string_view _folderPath, std::string_view _name) : folderPath(_folderPath), name(_name), status(Status::Uninitialized) {
|
||||
if (folderPath.empty()) {
|
||||
assetId = name;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
assetId = folderPath + "/" + name;
|
||||
}
|
||||
}
|
||||
|
||||
Asset::~Asset() {}
|
||||
|
||||
Asset::~Asset()
|
||||
{
|
||||
}
|
||||
std::string Asset::getFolderPath() const { return folderPath; }
|
||||
|
||||
std::string Asset::getFolderPath() const
|
||||
{
|
||||
return folderPath;
|
||||
}
|
||||
std::string Asset::getName() const { return name; }
|
||||
|
||||
std::string Asset::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string Asset::getAssetIdentifier() const
|
||||
{
|
||||
return assetId;
|
||||
}
|
||||
std::string Asset::getAssetIdentifier() const { return assetId; }
|
||||
|
||||
@@ -2,18 +2,11 @@
|
||||
#include "MinimalEngine.h"
|
||||
#include "Serialization/ArchiveBuffer.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Seele {
|
||||
DECLARE_NAME_REF(Gfx, Graphics)
|
||||
class Asset
|
||||
{
|
||||
public:
|
||||
enum class Status
|
||||
{
|
||||
Uninitialized,
|
||||
Loading,
|
||||
Ready
|
||||
};
|
||||
class Asset {
|
||||
public:
|
||||
enum class Status { Uninitialized, Loading, Ready };
|
||||
Asset();
|
||||
Asset(std::string_view folderPath, std::string_view name);
|
||||
virtual ~Asset();
|
||||
@@ -22,7 +15,7 @@ public:
|
||||
|
||||
virtual void save(ArchiveBuffer& buffer) const = 0;
|
||||
virtual void load(ArchiveBuffer& buffer) = 0;
|
||||
|
||||
|
||||
bool isModified() const;
|
||||
// returns the assets name
|
||||
std::string getName() const;
|
||||
@@ -31,15 +24,10 @@ public:
|
||||
// returns the identifier with which it can be found from the asset registry
|
||||
std::string getAssetIdentifier() const;
|
||||
|
||||
constexpr Status getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
constexpr void setStatus(Status _status)
|
||||
{
|
||||
status = _status;
|
||||
}
|
||||
protected:
|
||||
constexpr Status getStatus() { return status; }
|
||||
constexpr void setStatus(Status _status) { status = _status; }
|
||||
|
||||
protected:
|
||||
std::string folderPath;
|
||||
std::string name;
|
||||
std::string assetId;
|
||||
|
||||
@@ -1,134 +1,96 @@
|
||||
#include "AssetRegistry.h"
|
||||
#include "MeshAsset.h"
|
||||
#include "FontAsset.h"
|
||||
#include "TextureAsset.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Mesh.h"
|
||||
#include "MaterialAsset.h"
|
||||
#include "MaterialInstanceAsset.h"
|
||||
#include "Graphics/Mesh.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Window/WindowManager.h"
|
||||
#include "MeshAsset.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <iostream>
|
||||
#include "TextureAsset.h"
|
||||
#include "Window/WindowManager.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
AssetRegistry* _instance = new AssetRegistry();
|
||||
|
||||
AssetRegistry::~AssetRegistry()
|
||||
{
|
||||
delete assetRoot;
|
||||
}
|
||||
AssetRegistry::~AssetRegistry() { delete assetRoot; }
|
||||
|
||||
void AssetRegistry::init(std::filesystem::path rootFolder, Gfx::PGraphics graphics)
|
||||
{
|
||||
get().initialize(rootFolder, graphics);
|
||||
}
|
||||
void AssetRegistry::init(std::filesystem::path rootFolder, Gfx::PGraphics graphics) { get().initialize(rootFolder, graphics); }
|
||||
|
||||
PMeshAsset AssetRegistry::findMesh(std::string_view folderPath, std::string_view filePath)
|
||||
{
|
||||
PMeshAsset AssetRegistry::findMesh(std::string_view folderPath, std::string_view filePath) {
|
||||
AssetFolder* folder = get().assetRoot;
|
||||
if (!folderPath.empty())
|
||||
{
|
||||
if (!folderPath.empty()) {
|
||||
folder = get().getOrCreateFolder(folderPath);
|
||||
}
|
||||
return folder->meshes.at(std::string(filePath));
|
||||
}
|
||||
|
||||
PTextureAsset AssetRegistry::findTexture(std::string_view folderPath, std::string_view filePath)
|
||||
{
|
||||
PTextureAsset AssetRegistry::findTexture(std::string_view folderPath, std::string_view filePath) {
|
||||
AssetFolder* folder = get().assetRoot;
|
||||
if (!folderPath.empty())
|
||||
{
|
||||
if (!folderPath.empty()) {
|
||||
folder = get().getOrCreateFolder(folderPath);
|
||||
}
|
||||
return folder->textures.at(std::string(filePath));
|
||||
}
|
||||
|
||||
PFontAsset AssetRegistry::findFont(std::string_view folderPath, std::string_view filePath)
|
||||
{
|
||||
PFontAsset AssetRegistry::findFont(std::string_view folderPath, std::string_view filePath) {
|
||||
AssetFolder* folder = get().assetRoot;
|
||||
if (!folderPath.empty())
|
||||
{
|
||||
if (!folderPath.empty()) {
|
||||
folder = get().getOrCreateFolder(folderPath);
|
||||
}
|
||||
return folder->fonts.at(std::string(filePath));
|
||||
}
|
||||
|
||||
PMaterialAsset AssetRegistry::findMaterial(std::string_view folderPath, std::string_view filePath)
|
||||
{
|
||||
PMaterialAsset AssetRegistry::findMaterial(std::string_view folderPath, std::string_view filePath) {
|
||||
AssetFolder* folder = get().assetRoot;
|
||||
if (!folderPath.empty())
|
||||
{
|
||||
if (!folderPath.empty()) {
|
||||
folder = get().getOrCreateFolder(folderPath);
|
||||
}
|
||||
return folder->materials.at(std::string(filePath));
|
||||
}
|
||||
|
||||
PMaterialInstanceAsset AssetRegistry::findMaterialInstance(std::string_view folderPath, std::string_view filePath)
|
||||
{
|
||||
PMaterialInstanceAsset AssetRegistry::findMaterialInstance(std::string_view folderPath, std::string_view filePath) {
|
||||
AssetFolder* folder = get().assetRoot;
|
||||
if (!folderPath.empty())
|
||||
{
|
||||
if (!folderPath.empty()) {
|
||||
folder = get().getOrCreateFolder(folderPath);
|
||||
}
|
||||
return folder->instances.at(std::string(filePath));
|
||||
}
|
||||
|
||||
std::ofstream AssetRegistry::createWriteStream(const std::filesystem::path& relativePath, std::ios_base::openmode openmode)
|
||||
{
|
||||
std::ofstream AssetRegistry::createWriteStream(const std::filesystem::path& relativePath, std::ios_base::openmode openmode) {
|
||||
return get().internalCreateWriteStream(relativePath, openmode);
|
||||
}
|
||||
|
||||
std::ifstream AssetRegistry::createReadStream(const std::filesystem::path& relativePath, std::ios_base::openmode openmode)
|
||||
{
|
||||
std::ifstream AssetRegistry::createReadStream(const std::filesystem::path& relativePath, std::ios_base::openmode openmode) {
|
||||
return get().internalCreateReadStream(relativePath, openmode);
|
||||
}
|
||||
|
||||
AssetRegistry &AssetRegistry::get()
|
||||
{
|
||||
return *_instance;
|
||||
}
|
||||
AssetRegistry& AssetRegistry::get() { return *_instance; }
|
||||
|
||||
AssetRegistry::AssetRegistry()
|
||||
: assetRoot(nullptr)
|
||||
{
|
||||
}
|
||||
AssetRegistry::AssetRegistry() : assetRoot(nullptr) {}
|
||||
|
||||
AssetRegistry* AssetRegistry::getInstance()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
AssetRegistry* AssetRegistry::getInstance() { return _instance; }
|
||||
|
||||
void AssetRegistry::loadRegistry()
|
||||
{
|
||||
get().loadRegistryInternal();
|
||||
}
|
||||
void AssetRegistry::loadRegistry() { get().loadRegistryInternal(); }
|
||||
|
||||
void AssetRegistry::saveRegistry()
|
||||
{
|
||||
get().saveRegistryInternal();
|
||||
}
|
||||
void AssetRegistry::saveRegistry() { get().saveRegistryInternal(); }
|
||||
|
||||
AssetRegistry::AssetFolder* AssetRegistry::getOrCreateFolder(std::string_view fullPath)
|
||||
{
|
||||
AssetRegistry::AssetFolder* AssetRegistry::getOrCreateFolder(std::string_view fullPath) {
|
||||
AssetFolder* result = assetRoot;
|
||||
std::string temp = std::string(fullPath);
|
||||
while (!temp.empty())
|
||||
{
|
||||
while (!temp.empty()) {
|
||||
size_t slashLoc = temp.find("/");
|
||||
if (slashLoc == std::string::npos)
|
||||
{
|
||||
if (!result->children.contains(temp))
|
||||
{
|
||||
if (slashLoc == std::string::npos) {
|
||||
if (!result->children.contains(temp)) {
|
||||
result->children[temp] = new AssetFolder(temp);
|
||||
}
|
||||
return result->children[temp];
|
||||
}
|
||||
std::string folderName = temp.substr(0, slashLoc);
|
||||
if (!result->children.contains(folderName))
|
||||
{
|
||||
if (!result->children.contains(folderName)) {
|
||||
result->children[folderName] = new AssetFolder(fullPath);
|
||||
}
|
||||
result = result->children[folderName];
|
||||
@@ -137,40 +99,31 @@ AssetRegistry::AssetFolder* AssetRegistry::getOrCreateFolder(std::string_view fu
|
||||
return result;
|
||||
}
|
||||
|
||||
void AssetRegistry::initialize(const std::filesystem::path &_rootFolder, Gfx::PGraphics _graphics)
|
||||
{
|
||||
void AssetRegistry::initialize(const std::filesystem::path& _rootFolder, Gfx::PGraphics _graphics) {
|
||||
this->graphics = _graphics;
|
||||
this->rootFolder = _rootFolder;
|
||||
this->assetRoot = new AssetFolder("");
|
||||
loadRegistryInternal();
|
||||
}
|
||||
|
||||
void AssetRegistry::loadRegistryInternal()
|
||||
{
|
||||
void AssetRegistry::loadRegistryInternal() {
|
||||
peekFolder(assetRoot);
|
||||
loadFolder(assetRoot);
|
||||
}
|
||||
|
||||
void AssetRegistry::peekFolder(AssetFolder* folder)
|
||||
{
|
||||
for (const auto& entry : std::filesystem::directory_iterator(rootFolder / folder->folderPath))
|
||||
{
|
||||
void AssetRegistry::peekFolder(AssetFolder* folder) {
|
||||
for (const auto& entry : std::filesystem::directory_iterator(rootFolder / folder->folderPath)) {
|
||||
const auto& stem = entry.path().stem().string();
|
||||
if (entry.is_directory())
|
||||
{
|
||||
if (folder->folderPath.empty())
|
||||
{
|
||||
if (entry.is_directory()) {
|
||||
if (folder->folderPath.empty()) {
|
||||
folder->children[stem] = new AssetFolder(stem);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
folder->children[stem] = new AssetFolder(folder->folderPath + "/" + stem);
|
||||
}
|
||||
peekFolder(folder->children[stem]);
|
||||
continue;
|
||||
}
|
||||
if(entry.path().filename().compare(".DS_Store") == 0)
|
||||
{
|
||||
if (entry.path().filename().compare(".DS_Store") == 0) {
|
||||
continue;
|
||||
}
|
||||
auto stream = std::ifstream(entry.path(), std::ios::binary);
|
||||
@@ -181,20 +134,16 @@ void AssetRegistry::peekFolder(AssetFolder* folder)
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRegistry::loadFolder(AssetFolder* folder)
|
||||
{
|
||||
for (const auto& entry : std::filesystem::directory_iterator(rootFolder / folder->folderPath))
|
||||
{
|
||||
void AssetRegistry::loadFolder(AssetFolder* folder) {
|
||||
for (const auto& entry : std::filesystem::directory_iterator(rootFolder / folder->folderPath)) {
|
||||
const auto& path = entry.path();
|
||||
if (entry.is_directory())
|
||||
{
|
||||
if (entry.is_directory()) {
|
||||
auto relative = path.stem().string();
|
||||
loadFolder(folder->children[relative]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(entry.path().filename().compare(".DS_Store") == 0)
|
||||
{
|
||||
if (entry.path().filename().compare(".DS_Store") == 0) {
|
||||
continue;
|
||||
}
|
||||
auto stream = std::ifstream(path, std::ios::binary);
|
||||
@@ -205,8 +154,7 @@ void AssetRegistry::loadFolder(AssetFolder* folder)
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRegistry::peekAsset(ArchiveBuffer& buffer)
|
||||
{
|
||||
void AssetRegistry::peekAsset(ArchiveBuffer& buffer) {
|
||||
// Read asset type
|
||||
uint64 identifier;
|
||||
Serialization::load(buffer, identifier);
|
||||
@@ -222,8 +170,7 @@ void AssetRegistry::peekAsset(ArchiveBuffer& buffer)
|
||||
AssetFolder* folder = getOrCreateFolder(folderPath);
|
||||
|
||||
OAsset asset;
|
||||
switch (identifier)
|
||||
{
|
||||
switch (identifier) {
|
||||
case TextureAsset::IDENTIFIER:
|
||||
asset = new TextureAsset(folderPath, name);
|
||||
folder->textures[name] = std::move(asset);
|
||||
@@ -249,8 +196,7 @@ void AssetRegistry::peekAsset(ArchiveBuffer& buffer)
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRegistry::loadAsset(ArchiveBuffer& buffer)
|
||||
{
|
||||
void AssetRegistry::loadAsset(ArchiveBuffer& buffer) {
|
||||
// Read asset type
|
||||
uint64 identifier;
|
||||
Serialization::load(buffer, identifier);
|
||||
@@ -264,10 +210,9 @@ void AssetRegistry::loadAsset(ArchiveBuffer& buffer)
|
||||
Serialization::load(buffer, folderPath);
|
||||
|
||||
AssetFolder* folder = getOrCreateFolder(folderPath);
|
||||
|
||||
|
||||
PAsset asset;
|
||||
switch (identifier)
|
||||
{
|
||||
switch (identifier) {
|
||||
case TextureAsset::IDENTIFIER:
|
||||
asset = PTextureAsset(folder->textures.at(name));
|
||||
break;
|
||||
@@ -289,42 +234,31 @@ void AssetRegistry::loadAsset(ArchiveBuffer& buffer)
|
||||
asset->load(buffer);
|
||||
}
|
||||
|
||||
void AssetRegistry::saveRegistryInternal()
|
||||
{
|
||||
saveFolder("", assetRoot);
|
||||
}
|
||||
void AssetRegistry::saveRegistryInternal() { saveFolder("", assetRoot); }
|
||||
|
||||
void AssetRegistry::saveFolder(const std::filesystem::path& folderPath, AssetFolder* folder)
|
||||
{
|
||||
void AssetRegistry::saveFolder(const std::filesystem::path& folderPath, AssetFolder* folder) {
|
||||
std::filesystem::create_directory(rootFolder / folderPath);
|
||||
for (const auto& [name, texture] : folder->textures)
|
||||
{
|
||||
for (const auto& [name, texture] : folder->textures) {
|
||||
saveAsset(PTextureAsset(texture), TextureAsset::IDENTIFIER, folderPath, name);
|
||||
}
|
||||
for (const auto& [name, mesh] : folder->meshes)
|
||||
{
|
||||
for (const auto& [name, mesh] : folder->meshes) {
|
||||
saveAsset(PMeshAsset(mesh), MeshAsset::IDENTIFIER, folderPath, name);
|
||||
}
|
||||
for (const auto& [name, material] : folder->materials)
|
||||
{
|
||||
for (const auto& [name, material] : folder->materials) {
|
||||
saveAsset(PMaterialAsset(material), MaterialAsset::IDENTIFIER, folderPath, name);
|
||||
}
|
||||
for (const auto& [name, material] : folder->instances)
|
||||
{
|
||||
for (const auto& [name, material] : folder->instances) {
|
||||
saveAsset(PMaterialInstanceAsset(material), MaterialInstanceAsset::IDENTIFIER, folderPath, name);
|
||||
}
|
||||
for (const auto& [name, font] : folder->fonts)
|
||||
{
|
||||
for (const auto& [name, font] : folder->fonts) {
|
||||
saveAsset(PFontAsset(font), FontAsset::IDENTIFIER, folderPath, name);
|
||||
}
|
||||
for (auto& [name, child] : folder->children)
|
||||
{
|
||||
for (auto& [name, child] : folder->children) {
|
||||
saveFolder(folderPath / name, child);
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRegistry::saveAsset(PAsset asset, uint64 identifier, const std::filesystem::path& folderPath, std::string name)
|
||||
{
|
||||
void AssetRegistry::saveAsset(PAsset asset, uint64 identifier, const std::filesystem::path& folderPath, std::string name) {
|
||||
if (name.empty())
|
||||
return;
|
||||
|
||||
@@ -342,65 +276,49 @@ void AssetRegistry::saveAsset(PAsset asset, uint64 identifier, const std::filesy
|
||||
buffer.writeToStream(assetStream);
|
||||
}
|
||||
|
||||
std::filesystem::path AssetRegistry::getRootFolder()
|
||||
{
|
||||
return get().rootFolder;
|
||||
}
|
||||
std::filesystem::path AssetRegistry::getRootFolder() { return get().rootFolder; }
|
||||
|
||||
void AssetRegistry::registerMesh(OMeshAsset mesh)
|
||||
{
|
||||
void AssetRegistry::registerMesh(OMeshAsset mesh) {
|
||||
AssetFolder* folder = getOrCreateFolder(mesh->getFolderPath());
|
||||
folder->meshes[mesh->getName()] = std::move(mesh);
|
||||
}
|
||||
|
||||
void AssetRegistry::registerTexture(OTextureAsset texture)
|
||||
{
|
||||
void AssetRegistry::registerTexture(OTextureAsset texture) {
|
||||
AssetFolder* folder = getOrCreateFolder(texture->getFolderPath());
|
||||
folder->textures[texture->getName()] = std::move(texture);
|
||||
}
|
||||
|
||||
void AssetRegistry::registerFont(OFontAsset font)
|
||||
{
|
||||
void AssetRegistry::registerFont(OFontAsset font) {
|
||||
AssetFolder* folder = getOrCreateFolder(font->getFolderPath());
|
||||
folder->fonts[font->getName()] = std::move(font);
|
||||
}
|
||||
|
||||
void AssetRegistry::registerMaterial(OMaterialAsset material)
|
||||
{
|
||||
void AssetRegistry::registerMaterial(OMaterialAsset material) {
|
||||
AssetFolder* folder = getOrCreateFolder(material->getFolderPath());
|
||||
folder->materials[material->getName()] = std::move(material);
|
||||
}
|
||||
|
||||
void AssetRegistry::registerMaterialInstance(OMaterialInstanceAsset material)
|
||||
{
|
||||
void AssetRegistry::registerMaterialInstance(OMaterialInstanceAsset material) {
|
||||
AssetFolder* folder = getOrCreateFolder(material->getFolderPath());
|
||||
folder->instances[material->getName()] = std::move(material);
|
||||
}
|
||||
|
||||
|
||||
std::ofstream AssetRegistry::internalCreateWriteStream(const std::filesystem::path& relativePath, std::ios_base::openmode openmode)
|
||||
{
|
||||
std::ofstream AssetRegistry::internalCreateWriteStream(const std::filesystem::path& relativePath, std::ios_base::openmode openmode) {
|
||||
auto fullPath = rootFolder / relativePath;
|
||||
std::filesystem::create_directories(fullPath.parent_path());
|
||||
return std::ofstream(fullPath.string(), openmode);
|
||||
}
|
||||
|
||||
std::ifstream AssetRegistry::internalCreateReadStream(const std::filesystem::path& relativePath, std::ios_base::openmode openmode)
|
||||
{
|
||||
std::ifstream AssetRegistry::internalCreateReadStream(const std::filesystem::path& relativePath, std::ios_base::openmode openmode) {
|
||||
auto fullPath = rootFolder / relativePath;
|
||||
std::filesystem::create_directories(fullPath.parent_path());
|
||||
return std::ifstream(fullPath.string(), openmode);
|
||||
}
|
||||
|
||||
AssetRegistry::AssetFolder::AssetFolder(std::string_view folderPath)
|
||||
: folderPath(folderPath)
|
||||
{}
|
||||
AssetRegistry::AssetFolder::AssetFolder(std::string_view folderPath) : folderPath(folderPath) {}
|
||||
|
||||
AssetRegistry::AssetFolder::~AssetFolder()
|
||||
{
|
||||
for (auto [_, child] : children)
|
||||
{
|
||||
AssetRegistry::AssetFolder::~AssetFolder() {
|
||||
for (auto [_, child] : children) {
|
||||
delete child;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "Asset.h"
|
||||
#include "Containers/Map.h"
|
||||
#include <string>
|
||||
#include "MinimalEngine.h"
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
DECLARE_REF(TextureAsset)
|
||||
DECLARE_REF(FontAsset)
|
||||
DECLARE_REF(MeshAsset)
|
||||
DECLARE_REF(MaterialAsset)
|
||||
DECLARE_REF(MaterialInstanceAsset)
|
||||
DECLARE_NAME_REF(Gfx, Graphics)
|
||||
class AssetRegistry
|
||||
{
|
||||
public:
|
||||
class AssetRegistry {
|
||||
public:
|
||||
~AssetRegistry();
|
||||
static void init(std::filesystem::path path, Gfx::PGraphics graphics);
|
||||
|
||||
@@ -34,8 +33,7 @@ public:
|
||||
|
||||
static void loadRegistry();
|
||||
static void saveRegistry();
|
||||
struct AssetFolder
|
||||
{
|
||||
struct AssetFolder {
|
||||
std::string folderPath;
|
||||
Map<std::string, AssetFolder*> children;
|
||||
Map<std::string, OTextureAsset> textures;
|
||||
@@ -49,7 +47,8 @@ public:
|
||||
AssetFolder* getOrCreateFolder(std::string_view foldername);
|
||||
AssetRegistry();
|
||||
static AssetRegistry* getInstance();
|
||||
private:
|
||||
|
||||
private:
|
||||
static AssetRegistry& get();
|
||||
|
||||
void initialize(const std::filesystem::path& rootFolder, Gfx::PGraphics graphics);
|
||||
@@ -81,4 +80,4 @@ private:
|
||||
friend class MaterialLoader;
|
||||
friend class MeshLoader;
|
||||
};
|
||||
}
|
||||
} // namespace Seele
|
||||
@@ -5,26 +5,16 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
FontAsset::FontAsset()
|
||||
{
|
||||
}
|
||||
FontAsset::FontAsset() {}
|
||||
|
||||
FontAsset::FontAsset(std::string_view folderPath, std::string_view name)
|
||||
: Asset(folderPath, name)
|
||||
{
|
||||
}
|
||||
FontAsset::FontAsset(std::string_view folderPath, std::string_view name) : Asset(folderPath, name) {}
|
||||
|
||||
FontAsset::~FontAsset()
|
||||
{
|
||||
|
||||
}
|
||||
FontAsset::~FontAsset() {}
|
||||
|
||||
void FontAsset::save(ArchiveBuffer& buffer) const
|
||||
{
|
||||
void FontAsset::save(ArchiveBuffer& buffer) const {
|
||||
Serialization::save(buffer, glyphs);
|
||||
Serialization::save(buffer, usedTextures.size());
|
||||
for (uint32 x = 0; x < usedTextures.size(); ++x)
|
||||
{
|
||||
for (uint32 x = 0; x < usedTextures.size(); ++x) {
|
||||
Array<uint8> textureData;
|
||||
ktxTexture2* kTexture;
|
||||
ktxTextureCreateInfo createInfo = {
|
||||
@@ -34,7 +24,9 @@ void FontAsset::save(ArchiveBuffer& buffer) const
|
||||
.baseWidth = usedTextures[x]->getWidth(),
|
||||
.baseHeight = usedTextures[x]->getHeight(),
|
||||
.baseDepth = usedTextures[x]->getDepth(),
|
||||
.numDimensions = usedTextures[x]->getDepth() > 1 ? 3u : usedTextures[x]->getHeight() > 1 ? 2u : 1u,
|
||||
.numDimensions = usedTextures[x]->getDepth() > 1 ? 3u
|
||||
: usedTextures[x]->getHeight() > 1 ? 2u
|
||||
: 1u,
|
||||
.numLevels = usedTextures[x]->getMipLevels(),
|
||||
.numLayers = usedTextures[x]->getDepth(),
|
||||
.numFaces = usedTextures[x]->getNumFaces(),
|
||||
@@ -43,10 +35,8 @@ void FontAsset::save(ArchiveBuffer& buffer) const
|
||||
};
|
||||
ktxTexture2_Create(&createInfo, KTX_TEXTURE_CREATE_ALLOC_STORAGE, &kTexture);
|
||||
|
||||
for (uint32 depth = 0; depth < usedTextures[x]->getDepth(); ++depth)
|
||||
{
|
||||
for (uint32 face = 0; face < usedTextures[x]->getNumFaces(); ++face)
|
||||
{
|
||||
for (uint32 depth = 0; depth < usedTextures[x]->getDepth(); ++depth) {
|
||||
for (uint32 face = 0; face < usedTextures[x]->getNumFaces(); ++face) {
|
||||
// technically, downloading cant be const, because we have to allocate temporary buffers and change layouts
|
||||
// but practically the texture stays the same
|
||||
const_cast<Gfx::Texture2D*>(*(usedTextures[x]))->download(0, depth, face, textureData);
|
||||
@@ -55,9 +45,7 @@ void FontAsset::save(ArchiveBuffer& buffer) const
|
||||
}
|
||||
char writer[100];
|
||||
snprintf(writer, sizeof(writer), "%s version %s", "SeeleEngine", "0.0.1");
|
||||
ktxHashList_AddKVPair(&kTexture->kvDataHead, KTX_WRITER_KEY,
|
||||
(ktx_uint32_t)strlen(writer) + 1,
|
||||
writer);
|
||||
ktxHashList_AddKVPair(&kTexture->kvDataHead, KTX_WRITER_KEY, (ktx_uint32_t)strlen(writer) + 1, writer);
|
||||
|
||||
ktxTexture2_TranscodeBasis(kTexture, KTX_TTF_ASTC_4x4_RGBA, 0);
|
||||
|
||||
@@ -74,31 +62,26 @@ void FontAsset::save(ArchiveBuffer& buffer) const
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FontAsset::load(ArchiveBuffer& buffer)
|
||||
{
|
||||
void FontAsset::load(ArchiveBuffer& buffer) {
|
||||
Serialization::load(buffer, glyphs);
|
||||
size_t numTextures;
|
||||
Serialization::load(buffer, numTextures);
|
||||
for (uint64 x = 0; x < numTextures; ++x)
|
||||
{
|
||||
for (uint64 x = 0; x < numTextures; ++x) {
|
||||
Array<uint8> rawTex;
|
||||
Serialization::load(buffer, rawTex);
|
||||
|
||||
ktxTexture2* kTexture;
|
||||
ktxTexture2_CreateFromMemory(rawTex.data(),
|
||||
rawTex.size(),
|
||||
KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT,
|
||||
&kTexture);
|
||||
ktxTexture2_CreateFromMemory(rawTex.data(), rawTex.size(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &kTexture);
|
||||
|
||||
ktxTexture2_TranscodeBasis(kTexture, KTX_TTF_BC7_RGBA, 0);
|
||||
|
||||
TextureCreateInfo createInfo = {
|
||||
.sourceData = {
|
||||
.size = ktxTexture_GetDataSize(ktxTexture(kTexture)),
|
||||
.data = ktxTexture_GetData(ktxTexture(kTexture)),
|
||||
.owner = Gfx::QueueType::GRAPHICS,
|
||||
},
|
||||
.sourceData =
|
||||
{
|
||||
.size = ktxTexture_GetDataSize(ktxTexture(kTexture)),
|
||||
.data = ktxTexture_GetData(ktxTexture(kTexture)),
|
||||
.owner = Gfx::QueueType::GRAPHICS,
|
||||
},
|
||||
.format = (Gfx::SeFormat)kTexture->vkFormat,
|
||||
.width = kTexture->baseWidth,
|
||||
.height = kTexture->baseHeight,
|
||||
@@ -116,21 +99,16 @@ void FontAsset::load(ArchiveBuffer& buffer)
|
||||
}
|
||||
}
|
||||
|
||||
void Seele::FontAsset::setUsedTextures(Array<Gfx::OTexture2D> _usedTextures)
|
||||
{
|
||||
usedTextures = std::move(_usedTextures);
|
||||
}
|
||||
void Seele::FontAsset::setUsedTextures(Array<Gfx::OTexture2D> _usedTextures) { usedTextures = std::move(_usedTextures); }
|
||||
|
||||
void FontAsset::Glyph::save(ArchiveBuffer& buffer) const
|
||||
{
|
||||
void FontAsset::Glyph::save(ArchiveBuffer& buffer) const {
|
||||
Serialization::save(buffer, textureIndex);
|
||||
Serialization::save(buffer, size);
|
||||
Serialization::save(buffer, bearing);
|
||||
Serialization::save(buffer, advance);
|
||||
}
|
||||
|
||||
void FontAsset::Glyph::load(ArchiveBuffer& buffer)
|
||||
{
|
||||
void FontAsset::Glyph::load(ArchiveBuffer& buffer) {
|
||||
Serialization::load(buffer, textureIndex);
|
||||
Serialization::load(buffer, size);
|
||||
Serialization::load(buffer, bearing);
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
#include "Containers/Map.h"
|
||||
#include "Math/Math.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Seele {
|
||||
DECLARE_NAME_REF(Gfx, Texture2D)
|
||||
class FontAsset : public Asset
|
||||
{
|
||||
public:
|
||||
class FontAsset : public Asset {
|
||||
public:
|
||||
static constexpr uint64 IDENTIFIER = 0x10;
|
||||
FontAsset();
|
||||
FontAsset(std::string_view folderPath, std::string_view name);
|
||||
@@ -16,8 +14,7 @@ public:
|
||||
virtual void save(ArchiveBuffer& buffer) const override;
|
||||
virtual void load(ArchiveBuffer& buffer) override;
|
||||
|
||||
struct Glyph
|
||||
{
|
||||
struct Glyph {
|
||||
uint32 textureIndex;
|
||||
IVector2 size;
|
||||
IVector2 bearing;
|
||||
@@ -28,7 +25,8 @@ public:
|
||||
const Map<uint32, Glyph> getGlyphData() const { return glyphs; }
|
||||
Gfx::PTexture2D getTexture(uint32 index) { return usedTextures[index]; }
|
||||
void setUsedTextures(Array<Gfx::OTexture2D> _usedTextures);
|
||||
private:
|
||||
|
||||
private:
|
||||
Array<Gfx::OTexture2D> usedTextures;
|
||||
Map<uint32, Glyph> glyphs;
|
||||
friend class FontLoader;
|
||||
|
||||
@@ -2,28 +2,12 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
LevelAsset::LevelAsset()
|
||||
{
|
||||
|
||||
}
|
||||
LevelAsset::LevelAsset() {}
|
||||
|
||||
LevelAsset::LevelAsset(std::string_view folderPath, std::string_view name)
|
||||
: Asset(folderPath, name)
|
||||
{
|
||||
|
||||
}
|
||||
LevelAsset::LevelAsset(std::string_view folderPath, std::string_view name) : Asset(folderPath, name) {}
|
||||
|
||||
LevelAsset::~LevelAsset()
|
||||
{
|
||||
|
||||
}
|
||||
LevelAsset::~LevelAsset() {}
|
||||
|
||||
void LevelAsset::save(ArchiveBuffer&) const
|
||||
{
|
||||
|
||||
}
|
||||
void LevelAsset::save(ArchiveBuffer&) const {}
|
||||
|
||||
void LevelAsset::load(ArchiveBuffer&)
|
||||
{
|
||||
|
||||
}
|
||||
void LevelAsset::load(ArchiveBuffer&) {}
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
#pragma once
|
||||
#include "Asset.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class LevelAsset : public Asset
|
||||
{
|
||||
public:
|
||||
namespace Seele {
|
||||
class LevelAsset : public Asset {
|
||||
public:
|
||||
static constexpr uint64 IDENTIFIER = 0x20;
|
||||
LevelAsset();
|
||||
LevelAsset(std::string_view folderPath, std::string_view name);
|
||||
virtual ~LevelAsset();
|
||||
virtual void save(ArchiveBuffer& buffer) const override;
|
||||
virtual void load(ArchiveBuffer& buffer) override;
|
||||
private:
|
||||
|
||||
private:
|
||||
};
|
||||
} // namespace Seele
|
||||
|
||||
@@ -1,38 +1,27 @@
|
||||
#include "MaterialAsset.h"
|
||||
#include "Material/Material.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "MaterialInstanceAsset.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Material/Material.h"
|
||||
#include "MaterialInstanceAsset.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
MaterialAsset::MaterialAsset()
|
||||
{
|
||||
}
|
||||
MaterialAsset::MaterialAsset() {}
|
||||
|
||||
MaterialAsset::MaterialAsset(std::string_view folderPath, std::string_view name)
|
||||
: Asset(folderPath, name)
|
||||
{
|
||||
}
|
||||
MaterialAsset::MaterialAsset(std::string_view folderPath, std::string_view name) : Asset(folderPath, name) {}
|
||||
|
||||
MaterialAsset::~MaterialAsset()
|
||||
{
|
||||
}
|
||||
MaterialAsset::~MaterialAsset() {}
|
||||
|
||||
void MaterialAsset::save(ArchiveBuffer& buffer) const
|
||||
{
|
||||
material->save(buffer);
|
||||
}
|
||||
void MaterialAsset::save(ArchiveBuffer& buffer) const { material->save(buffer); }
|
||||
|
||||
void MaterialAsset::load(ArchiveBuffer& buffer)
|
||||
{
|
||||
void MaterialAsset::load(ArchiveBuffer& buffer) {
|
||||
material = new Material();
|
||||
material->load(buffer);
|
||||
material->compile();
|
||||
}
|
||||
|
||||
PMaterialInstanceAsset MaterialAsset::instantiate(const InstantiationParameter& params)
|
||||
{
|
||||
PMaterialInstanceAsset MaterialAsset::instantiate(const InstantiationParameter& params) {
|
||||
OMaterialInstance instance = material->instantiate();
|
||||
instance->setBaseMaterial(this);
|
||||
OMaterialInstanceAsset asset = new MaterialInstanceAsset(params.folderPath, params.name);
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
#pragma once
|
||||
#include "Asset.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Seele {
|
||||
DECLARE_REF(Material)
|
||||
DECLARE_REF(MaterialInstanceAsset)
|
||||
struct InstantiationParameter
|
||||
{
|
||||
struct InstantiationParameter {
|
||||
std::string name;
|
||||
std::string folderPath;
|
||||
};
|
||||
class MaterialAsset : public Asset
|
||||
{
|
||||
public:
|
||||
class MaterialAsset : public Asset {
|
||||
public:
|
||||
static constexpr uint64 IDENTIFIER = 0x4;
|
||||
MaterialAsset();
|
||||
MaterialAsset(std::string_view folderPath, std::string_view name);
|
||||
@@ -21,7 +18,8 @@ public:
|
||||
virtual void load(ArchiveBuffer& buffer) override;
|
||||
PMaterial getMaterial() const { return material; }
|
||||
PMaterialInstanceAsset instantiate(const InstantiationParameter& params);
|
||||
private:
|
||||
|
||||
private:
|
||||
OMaterial material;
|
||||
friend class MaterialLoader;
|
||||
friend class MeshLoader;
|
||||
|
||||
@@ -1,34 +1,25 @@
|
||||
#include "MaterialInstanceAsset.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "Material/Material.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Material/Material.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
MaterialInstanceAsset::MaterialInstanceAsset()
|
||||
{
|
||||
}
|
||||
MaterialInstanceAsset::MaterialInstanceAsset() {}
|
||||
|
||||
MaterialInstanceAsset::MaterialInstanceAsset(std::string_view folderPath, std::string_view name)
|
||||
: Asset(folderPath, name)
|
||||
{
|
||||
}
|
||||
MaterialInstanceAsset::MaterialInstanceAsset(std::string_view folderPath, std::string_view name) : Asset(folderPath, name) {}
|
||||
|
||||
MaterialInstanceAsset::~MaterialInstanceAsset()
|
||||
{
|
||||
}
|
||||
MaterialInstanceAsset::~MaterialInstanceAsset() {}
|
||||
|
||||
|
||||
void MaterialInstanceAsset::save(ArchiveBuffer& buffer) const
|
||||
{
|
||||
void MaterialInstanceAsset::save(ArchiveBuffer& buffer) const {
|
||||
Serialization::save(buffer, baseMaterial->getFolderPath());
|
||||
Serialization::save(buffer, baseMaterial->getName());
|
||||
material->save(buffer);
|
||||
}
|
||||
|
||||
void MaterialInstanceAsset::load(ArchiveBuffer& buffer)
|
||||
{
|
||||
void MaterialInstanceAsset::load(ArchiveBuffer& buffer) {
|
||||
std::string folder;
|
||||
Serialization::load(buffer, folder);
|
||||
std::string id;
|
||||
|
||||
@@ -2,11 +2,9 @@
|
||||
#include "Asset.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class MaterialInstanceAsset : public Asset
|
||||
{
|
||||
public:
|
||||
namespace Seele {
|
||||
class MaterialInstanceAsset : public Asset {
|
||||
public:
|
||||
static constexpr uint64 IDENTIFIER = 0x8;
|
||||
MaterialInstanceAsset();
|
||||
MaterialInstanceAsset(std::string_view folderPath, std::string_view name);
|
||||
@@ -16,7 +14,8 @@ public:
|
||||
void setHandle(OMaterialInstance handle) { material = std::move(handle); }
|
||||
void setBase(PMaterialAsset base) { baseMaterial = base; }
|
||||
PMaterialInstance getHandle() const { return material; }
|
||||
private:
|
||||
|
||||
private:
|
||||
OMaterialInstance material;
|
||||
PMaterialAsset baseMaterial;
|
||||
};
|
||||
|
||||
@@ -1,29 +1,17 @@
|
||||
#include "MeshAsset.h"
|
||||
#include "AssetRegistry.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Mesh.h"
|
||||
#include "AssetRegistry.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
MeshAsset::MeshAsset()
|
||||
{
|
||||
}
|
||||
MeshAsset::MeshAsset() {}
|
||||
|
||||
MeshAsset::MeshAsset(std::string_view folderPath, std::string_view name)
|
||||
: Asset(folderPath, name)
|
||||
{
|
||||
}
|
||||
MeshAsset::MeshAsset(std::string_view folderPath, std::string_view name) : Asset(folderPath, name) {}
|
||||
|
||||
MeshAsset::~MeshAsset()
|
||||
{
|
||||
}
|
||||
MeshAsset::~MeshAsset() {}
|
||||
|
||||
void MeshAsset::save(ArchiveBuffer& buffer) const
|
||||
{
|
||||
Serialization::save(buffer, meshes);
|
||||
}
|
||||
void MeshAsset::save(ArchiveBuffer& buffer) const { Serialization::save(buffer, meshes); }
|
||||
|
||||
void MeshAsset::load(ArchiveBuffer& buffer)
|
||||
{
|
||||
Serialization::load(buffer, meshes);
|
||||
}
|
||||
void MeshAsset::load(ArchiveBuffer& buffer) { Serialization::load(buffer, meshes); }
|
||||
|
||||
@@ -2,20 +2,18 @@
|
||||
#include "Asset.h"
|
||||
#include "Component/Collider.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Seele {
|
||||
DECLARE_REF(Mesh)
|
||||
DECLARE_REF(MaterialInterface)
|
||||
class MeshAsset : public Asset
|
||||
{
|
||||
public:
|
||||
class MeshAsset : public Asset {
|
||||
public:
|
||||
static constexpr uint64 IDENTIFIER = 0x2;
|
||||
MeshAsset();
|
||||
MeshAsset(std::string_view folderPath, std::string_view name);
|
||||
virtual ~MeshAsset();
|
||||
virtual void save(ArchiveBuffer& buffer) const override;
|
||||
virtual void load(ArchiveBuffer& buffer) override;
|
||||
//Workaround while no editor
|
||||
// Workaround while no editor
|
||||
Array<OMesh> meshes;
|
||||
Component::Collider physicsMesh;
|
||||
};
|
||||
|
||||
@@ -1,69 +1,67 @@
|
||||
#include "TextureAsset.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Window/WindowManager.h"
|
||||
#include "Graphics/Vulkan/Enums.h"
|
||||
#include "Graphics/Texture.h"
|
||||
#include "Graphics/Vulkan/Enums.h"
|
||||
#include "Window/WindowManager.h"
|
||||
#include "ktx.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
#define KTX_ASSERT(x) { auto error = x; if(error != KTX_SUCCESS) { std::cout << ktxErrorString(error) << std::endl; abort(); } }
|
||||
#define KTX_ASSERT(x) \
|
||||
{ \
|
||||
auto error = x; \
|
||||
if (error != KTX_SUCCESS) { \
|
||||
std::cout << ktxErrorString(error) << std::endl; \
|
||||
abort(); \
|
||||
} \
|
||||
}
|
||||
|
||||
TextureAsset::TextureAsset()
|
||||
{
|
||||
}
|
||||
TextureAsset::TextureAsset() {}
|
||||
|
||||
TextureAsset::TextureAsset(std::string_view folderPath, std::string_view name)
|
||||
: Asset(folderPath, name)
|
||||
{
|
||||
}
|
||||
TextureAsset::TextureAsset(std::string_view folderPath, std::string_view name) : Asset(folderPath, name) {}
|
||||
|
||||
TextureAsset::~TextureAsset()
|
||||
{
|
||||
}
|
||||
TextureAsset::~TextureAsset() {}
|
||||
|
||||
void TextureAsset::save(ArchiveBuffer& buffer) const
|
||||
{
|
||||
//ktxBasisParams basisParams = {
|
||||
// .structSize = sizeof(ktxBasisParams),
|
||||
// .uastc = true,
|
||||
// .threadCount = std::thread::hardware_concurrency(),
|
||||
// .normalMap = normalMap,
|
||||
// .uastcFlags = KTX_PACK_UASTC_LEVEL_VERYSLOW,
|
||||
// .uastcRDO = true,
|
||||
// .uastcRDOQualityScalar = 1,
|
||||
//};
|
||||
//KTX_ASSERT(ktxTexture2_CompressBasisEx(ktxHandle, &basisParams));
|
||||
//KTX_ASSERT(ktxTexture2_DeflateZstd(ktxHandle, 20));
|
||||
//ktx_uint8_t* texData;
|
||||
//ktx_size_t texSize;
|
||||
//KTX_ASSERT(ktxTexture_WriteToMemory(ktxTexture(ktxHandle), &texData, &texSize));
|
||||
void TextureAsset::save(ArchiveBuffer& buffer) const {
|
||||
// ktxBasisParams basisParams = {
|
||||
// .structSize = sizeof(ktxBasisParams),
|
||||
// .uastc = true,
|
||||
// .threadCount = std::thread::hardware_concurrency(),
|
||||
// .normalMap = normalMap,
|
||||
// .uastcFlags = KTX_PACK_UASTC_LEVEL_VERYSLOW,
|
||||
// .uastcRDO = true,
|
||||
// .uastcRDOQualityScalar = 1,
|
||||
// };
|
||||
// KTX_ASSERT(ktxTexture2_CompressBasisEx(ktxHandle, &basisParams));
|
||||
// KTX_ASSERT(ktxTexture2_DeflateZstd(ktxHandle, 20));
|
||||
// ktx_uint8_t* texData;
|
||||
// ktx_size_t texSize;
|
||||
// KTX_ASSERT(ktxTexture_WriteToMemory(ktxTexture(ktxHandle), &texData, &texSize));
|
||||
//
|
||||
//Array<uint8> rawData(texSize);
|
||||
//std::memcpy(rawData.data(), texData, texSize);
|
||||
//Serialization::save(buffer, rawData);
|
||||
//free(texData);
|
||||
// Array<uint8> rawData(texSize);
|
||||
// std::memcpy(rawData.data(), texData, texSize);
|
||||
// Serialization::save(buffer, rawData);
|
||||
// free(texData);
|
||||
}
|
||||
|
||||
void TextureAsset::load(ArchiveBuffer& buffer)
|
||||
{
|
||||
void TextureAsset::load(ArchiveBuffer& buffer) {
|
||||
std::string ktxPath;
|
||||
Serialization::load(buffer, ktxPath);
|
||||
ktxTexture2* ktxHandle;
|
||||
|
||||
KTX_ASSERT(ktxTexture_CreateFromNamedFile(ktxPath.c_str(),
|
||||
KTX_TEXTURE_CREATE_NO_FLAGS,
|
||||
(ktxTexture**)&ktxHandle));
|
||||
|
||||
KTX_ASSERT(ktxTexture_CreateFromNamedFile(ktxPath.c_str(), KTX_TEXTURE_CREATE_NO_FLAGS, (ktxTexture**)&ktxHandle));
|
||||
|
||||
KTX_ASSERT(ktxTexture2_TranscodeBasis(ktxHandle, KTX_TTF_BC7_RGBA, 0));
|
||||
|
||||
Gfx::PGraphics graphics = buffer.getGraphics();
|
||||
TextureCreateInfo createInfo = {
|
||||
.sourceData = {
|
||||
.size = ktxTexture_GetDataSize(ktxTexture(ktxHandle)),
|
||||
.data = ktxTexture_GetData(ktxTexture(ktxHandle)),
|
||||
.owner = Gfx::QueueType::TRANSFER,
|
||||
},
|
||||
.sourceData =
|
||||
{
|
||||
.size = ktxTexture_GetDataSize(ktxTexture(ktxHandle)),
|
||||
.data = ktxTexture_GetData(ktxTexture(ktxHandle)),
|
||||
.owner = Gfx::QueueType::TRANSFER,
|
||||
},
|
||||
.format = (Gfx::SeFormat)ktxHandle->vkFormat,
|
||||
.width = ktxHandle->baseWidth,
|
||||
.height = ktxHandle->baseHeight,
|
||||
@@ -73,34 +71,20 @@ void TextureAsset::load(ArchiveBuffer& buffer)
|
||||
.elements = ktxHandle->numLayers,
|
||||
.usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
|
||||
};
|
||||
if (ktxHandle->isCubemap)
|
||||
{
|
||||
if (ktxHandle->isCubemap) {
|
||||
texture = graphics->createTextureCube(createInfo);
|
||||
}
|
||||
else if (ktxHandle->isArray)
|
||||
{
|
||||
} else if (ktxHandle->isArray) {
|
||||
texture = graphics->createTexture3D(createInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
texture = graphics->createTexture2D(createInfo);
|
||||
}
|
||||
|
||||
|
||||
texture->transferOwnership(Gfx::QueueType::GRAPHICS);
|
||||
ktxTexture_Destroy(ktxTexture(ktxHandle));
|
||||
}
|
||||
|
||||
void TextureAsset::setTexture(Gfx::OTexture _texture)
|
||||
{
|
||||
texture = std::move(_texture);
|
||||
}
|
||||
void TextureAsset::setTexture(Gfx::OTexture _texture) { texture = std::move(_texture); }
|
||||
|
||||
uint32 TextureAsset::getWidth()
|
||||
{
|
||||
return texture->getWidth();
|
||||
}
|
||||
uint32 TextureAsset::getWidth() { return texture->getWidth(); }
|
||||
|
||||
uint32 TextureAsset::getHeight()
|
||||
{
|
||||
return texture->getHeight();
|
||||
}
|
||||
uint32 TextureAsset::getHeight() { return texture->getHeight(); }
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
#include "Asset.h"
|
||||
|
||||
struct ktxTexture2;
|
||||
namespace Seele
|
||||
{
|
||||
namespace Seele {
|
||||
DECLARE_NAME_REF(Gfx, Texture)
|
||||
class TextureAsset : public Asset
|
||||
{
|
||||
public:
|
||||
class TextureAsset : public Asset {
|
||||
public:
|
||||
static constexpr uint64 IDENTIFIER = 0x1;
|
||||
TextureAsset();
|
||||
TextureAsset(std::string_view folderPath, std::string_view name);
|
||||
@@ -15,13 +13,11 @@ public:
|
||||
virtual void save(ArchiveBuffer& buffer) const override;
|
||||
virtual void load(ArchiveBuffer& buffer) override;
|
||||
void setTexture(Gfx::OTexture _texture);
|
||||
Gfx::PTexture getTexture()
|
||||
{
|
||||
return texture;
|
||||
}
|
||||
Gfx::PTexture getTexture() { return texture; }
|
||||
uint32 getWidth();
|
||||
uint32 getHeight();
|
||||
private:
|
||||
|
||||
private:
|
||||
Gfx::OTexture texture;
|
||||
bool normalMap;
|
||||
friend class TextureLoader;
|
||||
|
||||
@@ -7,21 +7,14 @@ using namespace Seele;
|
||||
using namespace Seele::Component;
|
||||
using namespace Seele::Math;
|
||||
|
||||
Camera::Camera()
|
||||
: viewMatrix(Matrix4())
|
||||
, cameraPos(Vector())
|
||||
, bNeedsViewBuild(false)
|
||||
{
|
||||
yaw = -3.1415f/2;
|
||||
Camera::Camera() : viewMatrix(Matrix4()), cameraPos(Vector()), bNeedsViewBuild(false) {
|
||||
yaw = -3.1415f / 2;
|
||||
pitch = 0;
|
||||
}
|
||||
|
||||
Camera::~Camera()
|
||||
{
|
||||
}
|
||||
Camera::~Camera() {}
|
||||
|
||||
void Camera::mouseMove(float deltaYaw, float deltaPitch)
|
||||
{
|
||||
void Camera::mouseMove(float deltaYaw, float deltaPitch) {
|
||||
yaw += deltaYaw / 500.f;
|
||||
pitch += deltaPitch / 500.f;
|
||||
Vector cameraDirection = glm::normalize(Vector(cos(yaw) * cos(pitch), sin(pitch), sin(yaw) * cos(pitch)));
|
||||
@@ -30,26 +23,22 @@ void Camera::mouseMove(float deltaYaw, float deltaPitch)
|
||||
bNeedsViewBuild = true;
|
||||
}
|
||||
|
||||
void Camera::mouseScroll(float x)
|
||||
{
|
||||
getTransform().translate(getTransform().getForward()*x);
|
||||
void Camera::mouseScroll(float x) {
|
||||
getTransform().translate(getTransform().getForward() * x);
|
||||
bNeedsViewBuild = true;
|
||||
}
|
||||
|
||||
void Camera::moveX(float amount)
|
||||
{
|
||||
getTransform().translate(getTransform().getForward()*amount);
|
||||
void Camera::moveX(float amount) {
|
||||
getTransform().translate(getTransform().getForward() * amount);
|
||||
bNeedsViewBuild = true;
|
||||
}
|
||||
|
||||
void Camera::moveY(float amount)
|
||||
{
|
||||
getTransform().translate(getTransform().getRight()*amount);
|
||||
void Camera::moveY(float amount) {
|
||||
getTransform().translate(getTransform().getRight() * amount);
|
||||
bNeedsViewBuild = true;
|
||||
}
|
||||
|
||||
void Camera::buildViewMatrix()
|
||||
{
|
||||
void Camera::buildViewMatrix() {
|
||||
Vector eyePos = getTransform().getPosition();
|
||||
Vector lookAt = eyePos + getTransform().getForward();
|
||||
viewMatrix = glm::lookAt(eyePos, lookAt, Vector(0, 1, 0));
|
||||
|
||||
@@ -3,34 +3,28 @@
|
||||
#include "Math/Matrix.h"
|
||||
#include "Transform.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Component
|
||||
{
|
||||
struct Camera
|
||||
{
|
||||
namespace Seele {
|
||||
namespace Component {
|
||||
struct Camera {
|
||||
REQUIRE_COMPONENT(Transform)
|
||||
|
||||
|
||||
Camera();
|
||||
~Camera();
|
||||
|
||||
Matrix4 getViewMatrix() const
|
||||
{
|
||||
assert (!bNeedsViewBuild);
|
||||
Matrix4 getViewMatrix() const {
|
||||
assert(!bNeedsViewBuild);
|
||||
return viewMatrix;
|
||||
}
|
||||
Vector getCameraPosition() const
|
||||
{
|
||||
return cameraPos;
|
||||
}
|
||||
Vector getCameraPosition() const { return cameraPos; }
|
||||
void mouseMove(float deltaX, float deltaY);
|
||||
void mouseScroll(float x);
|
||||
void moveX(float amount);
|
||||
void moveY(float amount);
|
||||
void buildViewMatrix();
|
||||
|
||||
|
||||
bool mainCamera = false;
|
||||
private:
|
||||
|
||||
private:
|
||||
float yaw;
|
||||
float pitch;
|
||||
Matrix4 viewMatrix;
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Component;
|
||||
|
||||
Collider Collider::transform(const Transform& transform) const
|
||||
{
|
||||
Collider Collider::transform(const Transform& transform) const {
|
||||
return Collider{
|
||||
.type = this->type,
|
||||
.boundingbox = this->boundingbox.getTransformedBox(transform.toMatrix()),
|
||||
|
||||
@@ -2,17 +2,13 @@
|
||||
#include "Math/AABB.h"
|
||||
#include "ShapeBase.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Component
|
||||
{
|
||||
enum class ColliderType
|
||||
{
|
||||
namespace Seele {
|
||||
namespace Component {
|
||||
enum class ColliderType {
|
||||
STATIC,
|
||||
DYNAMIC,
|
||||
};
|
||||
struct Collider
|
||||
{
|
||||
struct Collider {
|
||||
ColliderType type = ColliderType::STATIC;
|
||||
AABB boundingbox;
|
||||
ShapeBase physicsMesh;
|
||||
|
||||
@@ -2,58 +2,41 @@
|
||||
#include <concepts>
|
||||
#include <tuple>
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
template<typename... Types>
|
||||
struct Dependencies;
|
||||
template<>
|
||||
struct Dependencies<>
|
||||
{
|
||||
namespace Seele {
|
||||
template <typename... Types> struct Dependencies;
|
||||
template <> struct Dependencies<> {
|
||||
int x;
|
||||
template<typename... Right>
|
||||
Dependencies<Right...> operator|(const Dependencies<Right...>&)
|
||||
{
|
||||
return Dependencies<Right...>();
|
||||
}
|
||||
template <typename... Right> Dependencies<Right...> operator|(const Dependencies<Right...>&) { return Dependencies<Right...>(); }
|
||||
};
|
||||
template<typename This, typename... Rest>
|
||||
struct Dependencies<This, Rest...> : public Dependencies<Rest...>
|
||||
{
|
||||
template<typename... Right>
|
||||
Dependencies<This, Rest..., Right...> operator|(const Dependencies<Right...>&)
|
||||
{
|
||||
template <typename This, typename... Rest> struct Dependencies<This, Rest...> : public Dependencies<Rest...> {
|
||||
template <typename... Right> Dependencies<This, Rest..., Right...> operator|(const Dependencies<Right...>&) {
|
||||
return Dependencies<This, Rest..., Right...>();
|
||||
}
|
||||
int x;
|
||||
};
|
||||
|
||||
namespace Component
|
||||
{
|
||||
template<typename Comp>
|
||||
Comp& getComponent();
|
||||
namespace Component {
|
||||
template <typename Comp> Comp& getComponent();
|
||||
}
|
||||
|
||||
template<typename Comp>
|
||||
template <typename Comp>
|
||||
concept has_dependencies = requires(Comp) { Comp::dependencies; };
|
||||
|
||||
#define REQUIRE_COMPONENT(x) \
|
||||
private: \
|
||||
x& get##x() { return getComponent<x>(); } \
|
||||
const x& get##x() const { return getComponent<x>(); } \
|
||||
public: \
|
||||
#define REQUIRE_COMPONENT(x) \
|
||||
private: \
|
||||
x& get##x() { return getComponent<x>(); } \
|
||||
const x& get##x() const { return getComponent<x>(); } \
|
||||
\
|
||||
public: \
|
||||
constexpr static Dependencies<x> dependencies = {};
|
||||
|
||||
#define DECLARE_COMPONENT(x) \
|
||||
void accessComponent(x& val); \
|
||||
template<> \
|
||||
x& getComponent<x>();
|
||||
|
||||
|
||||
#define DEFINE_COMPONENT(x) \
|
||||
thread_local x* tl_##x = nullptr; \
|
||||
void Seele::Component::accessComponent(x& ref) { tl_##x = &ref; } \
|
||||
template<> \
|
||||
x& Seele::Component::getComponent<x>() { return *tl_##x; }
|
||||
#define DECLARE_COMPONENT(x) \
|
||||
void accessComponent(x& val); \
|
||||
template <> x& getComponent<x>();
|
||||
|
||||
#define DEFINE_COMPONENT(x) \
|
||||
thread_local x* tl_##x = nullptr; \
|
||||
void Seele::Component::accessComponent(x& ref) { tl_##x = &ref; } \
|
||||
template <> x& Seele::Component::getComponent<x>() { return *tl_##x; }
|
||||
|
||||
} // namespace Seele
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
#pragma once
|
||||
#include "Math/Vector.h"
|
||||
namespace Seele
|
||||
{
|
||||
namespace Component
|
||||
{
|
||||
struct DirectionalLight
|
||||
{
|
||||
namespace Seele {
|
||||
namespace Component {
|
||||
struct DirectionalLight {
|
||||
Vector4 color;
|
||||
Vector4 direction;
|
||||
};
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
#pragma once
|
||||
#include "Graphics/Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Component
|
||||
{
|
||||
struct KeyboardInput
|
||||
{
|
||||
namespace Seele {
|
||||
namespace Component {
|
||||
struct KeyboardInput {
|
||||
Seele::StaticArray<bool, static_cast<size_t>(Seele::KeyCode::KEY_LAST)> keys;
|
||||
bool mouse1;
|
||||
bool mouse2;
|
||||
@@ -16,6 +13,6 @@ struct KeyboardInput
|
||||
float deltaY;
|
||||
float scrollX;
|
||||
float scrollY;
|
||||
};
|
||||
};
|
||||
} // namespace Component
|
||||
} // namespace Seele
|
||||
@@ -1,12 +1,9 @@
|
||||
#pragma once
|
||||
#include "Asset/MeshAsset.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Component
|
||||
{
|
||||
struct Mesh
|
||||
{
|
||||
namespace Seele {
|
||||
namespace Component {
|
||||
struct Mesh {
|
||||
PMeshAsset asset;
|
||||
bool isStatic = true;
|
||||
};
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
#pragma once
|
||||
#include "Math/Vector.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Component
|
||||
{
|
||||
struct PointLight
|
||||
{
|
||||
namespace Seele {
|
||||
namespace Component {
|
||||
struct PointLight {
|
||||
Vector4 positionWS;
|
||||
//Vector4 positionVS;
|
||||
// Vector4 positionVS;
|
||||
Vector4 colorRange;
|
||||
};
|
||||
} // namespace Component
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
#pragma once
|
||||
#include "Math/AABB.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Component
|
||||
{
|
||||
struct RigidBody
|
||||
{
|
||||
namespace Seele {
|
||||
namespace Component {
|
||||
struct RigidBody {
|
||||
float mass = 1.0f;
|
||||
Vector force;
|
||||
Vector torque;
|
||||
|
||||
@@ -4,14 +4,12 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Component;
|
||||
|
||||
|
||||
//https://people.eecs.berkeley.edu/~jfc/mirtich/massProps.html
|
||||
struct ComputationState
|
||||
{
|
||||
// https://people.eecs.berkeley.edu/~jfc/mirtich/massProps.html
|
||||
struct ComputationState {
|
||||
// compute physics properties
|
||||
int A; /* alpha */
|
||||
int B; /* beta */
|
||||
int C; /* gamma */
|
||||
int A; /* alpha */
|
||||
int B; /* beta */
|
||||
int C; /* gamma */
|
||||
|
||||
/* projection integrals */
|
||||
float P1, Pa, Pb, Paa, Pab, Pbb, Paaa, Paab, Pabb, Pbbb;
|
||||
@@ -24,28 +22,25 @@ struct ComputationState
|
||||
Vector T1, T2, TP;
|
||||
};
|
||||
|
||||
struct Face
|
||||
{
|
||||
struct Face {
|
||||
StaticArray<Vector, 3> vertices;
|
||||
Vector normal;
|
||||
float w;
|
||||
};
|
||||
|
||||
void computeProjectionIntegrals(Face& f, ComputationState& state)
|
||||
{
|
||||
void computeProjectionIntegrals(Face& f, ComputationState& state) {
|
||||
state.P1 = state.Pa = state.Pb = state.Paa = state.Pab = state.Pbb = state.Paaa = state.Paab = state.Pabb = state.Pbbb = 0.0;
|
||||
for(uint32_t i = 0; i < 3; ++i)
|
||||
{
|
||||
for (uint32_t i = 0; i < 3; ++i) {
|
||||
float a0 = f.vertices[i][state.A];
|
||||
float b0 = f.vertices[i][state.B];
|
||||
float a1 = f.vertices[(i+1)%3][state.A];
|
||||
float b1 = f.vertices[(i+1)%3][state.B];
|
||||
float a1 = f.vertices[(i + 1) % 3][state.A];
|
||||
float b1 = f.vertices[(i + 1) % 3][state.B];
|
||||
|
||||
float da = a1 - a0;
|
||||
float db = b1 - b0;
|
||||
|
||||
float a0_2 = a0 * a0, a0_3 = a0_2 * a0, a0_4 = a0_3 * a0;
|
||||
float b0_2 = b0 * b0, b0_3 = b0_2 * b0, b0_4 = b0_3 * b0;
|
||||
float b0_2 = b0 * b0, b0_3 = b0_2 * b0, b0_4 = b0_3 * b0;
|
||||
float a1_2 = a1 * a1, a1_3 = a1_2 * a1;
|
||||
float b1_2 = b1 * b1, b1_3 = b1_2 * b1;
|
||||
|
||||
@@ -87,10 +82,9 @@ void computeProjectionIntegrals(Face& f, ComputationState& state)
|
||||
state.Pabb /= -60.0;
|
||||
}
|
||||
|
||||
void computeFaceIntegrals(Face& f, ComputationState& state)
|
||||
{
|
||||
void computeFaceIntegrals(Face& f, ComputationState& state) {
|
||||
computeProjectionIntegrals(f, state);
|
||||
float k1 = 1.0f/f.normal[state.C];
|
||||
float k1 = 1.0f / f.normal[state.C];
|
||||
float k2 = k1 * k1;
|
||||
float k3 = k2 * k1;
|
||||
float k4 = k3 * k1;
|
||||
@@ -104,53 +98,46 @@ void computeFaceIntegrals(Face& f, ComputationState& state)
|
||||
|
||||
state.Faa = k1 * state.Paa;
|
||||
state.Fbb = k1 * state.Pbb;
|
||||
state.Fcc = k3 * (n[state.A] * n[state.A] * state.Paa
|
||||
+ 2 * n[state.A] * n[state.B] * state.Pab
|
||||
+ n[state.B] * n[state.B] * state.Pbb
|
||||
+ w * (2 * (n[state.A] * state.Pa + n[state.B] * state.Pb) + w * state.P1));
|
||||
|
||||
state.Fcc = k3 * (n[state.A] * n[state.A] * state.Paa + 2 * n[state.A] * n[state.B] * state.Pab + n[state.B] * n[state.B] * state.Pbb +
|
||||
w * (2 * (n[state.A] * state.Pa + n[state.B] * state.Pb) + w * state.P1));
|
||||
|
||||
state.Faaa = k1 * state.Paaa;
|
||||
state.Fbbb = k1 * state.Pbbb;
|
||||
state.Fccc = -k4 * (n[state.A] * n[state.A] * n[state.A] * state.Paaa
|
||||
+ 3 * n[state.A] * n[state.A] * n[state.B] * state.Paab
|
||||
+ 3 * n[state.A] * n[state.B] * n[state.B] * state.Pabb
|
||||
+ 3 * n[state.B] * n[state.B] * n[state.B] * state.Pbbb
|
||||
+ 3 * w * (n[state.A] * n[state.A] * state.Paa
|
||||
+ 2 * n[state.A] * n[state.B] * state.Pa
|
||||
+ n[state.B] * n[state.B] * state.Pbb)
|
||||
+ w * w *(3 * (n[state.A]*state.Pa + n[state.B]*state.Pb) + w * state.P1)
|
||||
);
|
||||
|
||||
state.Fccc =
|
||||
-k4 *
|
||||
(n[state.A] * n[state.A] * n[state.A] * state.Paaa + 3 * n[state.A] * n[state.A] * n[state.B] * state.Paab +
|
||||
3 * n[state.A] * n[state.B] * n[state.B] * state.Pabb + 3 * n[state.B] * n[state.B] * n[state.B] * state.Pbbb +
|
||||
3 * w * (n[state.A] * n[state.A] * state.Paa + 2 * n[state.A] * n[state.B] * state.Pa + n[state.B] * n[state.B] * state.Pbb) +
|
||||
w * w * (3 * (n[state.A] * state.Pa + n[state.B] * state.Pb) + w * state.P1));
|
||||
|
||||
state.Faab = k1 * state.Paab;
|
||||
state.Fbbc = -k2 * (n[state.A] * state.Paab + n[state.B] * state.Pbbb + w * state.Pbb);
|
||||
state.Fcca = k3 * (n[state.A] * n[state.A] * state.Paa + 2 * n[state.A] * n[state.B] * state.Paab + n[state.B] * n[state.B] * state.Pabb
|
||||
+ w * (2 * (n[state.A] * state.Paa + n[state.B] * state.Pab) + w * state.Pa));
|
||||
state.Fcca = k3 * (n[state.A] * n[state.A] * state.Paa + 2 * n[state.A] * n[state.B] * state.Paab +
|
||||
n[state.B] * n[state.B] * state.Pabb + w * (2 * (n[state.A] * state.Paa + n[state.B] * state.Pab) + w * state.Pa));
|
||||
}
|
||||
|
||||
void computeVolumeIntegrals(const Array<Vector> vertices, const Array<uint32>& indices, ComputationState& state)
|
||||
{
|
||||
void computeVolumeIntegrals(const Array<Vector> vertices, const Array<uint32>& indices, ComputationState& state) {
|
||||
std::memset(&state, 0, sizeof(ComputationState));
|
||||
for (size_t i = 0; i < indices.size(); i+=3)
|
||||
{
|
||||
for (size_t i = 0; i < indices.size(); i += 3) {
|
||||
Face f;
|
||||
f.vertices = {
|
||||
vertices[indices[i]],
|
||||
vertices[indices[i+1]],
|
||||
vertices[indices[i+2]],
|
||||
vertices[indices[i + 1]],
|
||||
vertices[indices[i + 2]],
|
||||
};
|
||||
|
||||
|
||||
Vector e1 = f.vertices[2] - f.vertices[0];
|
||||
Vector e2 = f.vertices[1] - f.vertices[0];
|
||||
f.normal = glm::normalize(glm::cross(e1, e2));
|
||||
f.w = - f.normal.x * f.vertices[0].x
|
||||
- f.normal.y * f.vertices[0].y
|
||||
- f.normal.z * f.vertices[0].z;
|
||||
|
||||
f.w = -f.normal.x * f.vertices[0].x - f.normal.y * f.vertices[0].y - f.normal.z * f.vertices[0].z;
|
||||
|
||||
float nx = std::abs(f.normal.x);
|
||||
float ny = std::abs(f.normal.y);
|
||||
float nz = std::abs(f.normal.z);
|
||||
if (nx > ny && nx > nz) state.C = 0;
|
||||
else state.C = (ny > nz) ? 1 : 2;
|
||||
if (nx > ny && nx > nz)
|
||||
state.C = 0;
|
||||
else
|
||||
state.C = (ny > nz) ? 1 : 2;
|
||||
state.A = (state.C + 1) % 3;
|
||||
state.B = (state.A + 1) % 3;
|
||||
|
||||
@@ -172,8 +159,8 @@ void computeVolumeIntegrals(const Array<Vector> vertices, const Array<uint32>& i
|
||||
state.TP /= 2.0f;
|
||||
}
|
||||
|
||||
void computePhysicsParamsForMesh(Array<Vector>& vertices, const Array<uint32>& indices, Matrix3& bodyInertia, Vector& centerOfMass, float& mass)
|
||||
{
|
||||
void computePhysicsParamsForMesh(Array<Vector>& vertices, const Array<uint32>& indices, Matrix3& bodyInertia, Vector& centerOfMass,
|
||||
float& mass) {
|
||||
ComputationState state;
|
||||
computeVolumeIntegrals(vertices, indices, state);
|
||||
float density = 1;
|
||||
@@ -183,9 +170,9 @@ void computePhysicsParamsForMesh(Array<Vector>& vertices, const Array<uint32>& i
|
||||
bodyInertia[0][0] = density * (state.T2.y + state.T2.z);
|
||||
bodyInertia[1][1] = density * (state.T2.z + state.T2.x);
|
||||
bodyInertia[2][2] = density * (state.T2.x + state.T2.y);
|
||||
bodyInertia[0][1] = bodyInertia[1][0] = - density * state.TP.x;
|
||||
bodyInertia[1][2] = bodyInertia[2][1] = - density * state.TP.y;
|
||||
bodyInertia[2][1] = bodyInertia[1][2] = - density * state.TP.z;
|
||||
bodyInertia[0][1] = bodyInertia[1][0] = -density * state.TP.x;
|
||||
bodyInertia[1][2] = bodyInertia[2][1] = -density * state.TP.y;
|
||||
bodyInertia[2][1] = bodyInertia[1][2] = -density * state.TP.z;
|
||||
|
||||
bodyInertia[0][0] -= mass * (r.y * r.y + r.z * r.z);
|
||||
bodyInertia[1][1] -= mass * (r.z * r.z + r.x * r.x);
|
||||
@@ -195,74 +182,61 @@ void computePhysicsParamsForMesh(Array<Vector>& vertices, const Array<uint32>& i
|
||||
bodyInertia[2][1] = bodyInertia[1][2] += mass * r.z * r.x;
|
||||
}
|
||||
|
||||
ShapeBase::ShapeBase()
|
||||
{
|
||||
|
||||
}
|
||||
ShapeBase::ShapeBase() {}
|
||||
|
||||
ShapeBase::ShapeBase(Array<Vector> vertices, Array<uint32> indices)
|
||||
: vertices(vertices)
|
||||
, indices(indices)
|
||||
{
|
||||
ShapeBase::ShapeBase(Array<Vector> vertices, Array<uint32> indices) : vertices(vertices), indices(indices) {
|
||||
computePhysicsParamsForMesh(vertices, indices, bodyInertia, centerOfMass, mass);
|
||||
}
|
||||
|
||||
ShapeBase ShapeBase::transform(const Component::Transform& transform) const
|
||||
{
|
||||
ShapeBase ShapeBase::transform(const Component::Transform& transform) const {
|
||||
ShapeBase result = *this;
|
||||
for(auto& vert : result.vertices)
|
||||
{
|
||||
for (auto& vert : result.vertices) {
|
||||
vert = transform.toMatrix() * Vector4(vert, 1.0f);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void ShapeBase::addCollider(Array<Vector> verts, Array<uint32> inds, Matrix4 matrix)
|
||||
{
|
||||
void ShapeBase::addCollider(Array<Vector> verts, Array<uint32> inds, Matrix4 matrix) {
|
||||
size_t indOffset = vertices.size();
|
||||
for(auto vert : verts)
|
||||
{
|
||||
for (auto vert : verts) {
|
||||
vertices.add(Vector(matrix * Vector4(vert, 1.0f)));
|
||||
}
|
||||
for(auto ind : inds)
|
||||
{
|
||||
for (auto ind : inds) {
|
||||
indices.add(ind + static_cast<uint32>(indOffset));
|
||||
}
|
||||
computePhysicsParamsForMesh(vertices, indices, bodyInertia, centerOfMass, mass);
|
||||
}
|
||||
|
||||
void ShapeBase::visualize() const
|
||||
{
|
||||
void ShapeBase::visualize() const {
|
||||
Array<DebugVertex> verts;
|
||||
for(uint32 i = 0; i < indices.size(); i+=3)
|
||||
{
|
||||
for (uint32 i = 0; i < indices.size(); i += 3) {
|
||||
verts.add(DebugVertex{
|
||||
.position = Vector(vertices[indices[i+0]]),
|
||||
.color = Vector(1, 0, 0),
|
||||
});
|
||||
|
||||
verts.add(DebugVertex{
|
||||
.position = Vector(vertices[indices[i+1]]),
|
||||
.position = Vector(vertices[indices[i + 0]]),
|
||||
.color = Vector(1, 0, 0),
|
||||
});
|
||||
|
||||
verts.add(DebugVertex{
|
||||
.position = Vector(vertices[indices[i+1]]),
|
||||
.position = Vector(vertices[indices[i + 1]]),
|
||||
.color = Vector(1, 0, 0),
|
||||
});
|
||||
|
||||
verts.add(DebugVertex{
|
||||
.position = Vector(vertices[indices[i+2]]),
|
||||
.position = Vector(vertices[indices[i + 1]]),
|
||||
.color = Vector(1, 0, 0),
|
||||
});
|
||||
|
||||
verts.add(DebugVertex{
|
||||
.position = Vector(vertices[indices[i+2]]),
|
||||
.position = Vector(vertices[indices[i + 2]]),
|
||||
.color = Vector(1, 0, 0),
|
||||
});
|
||||
|
||||
verts.add(DebugVertex{
|
||||
.position = Vector(vertices[indices[i+0]]),
|
||||
.position = Vector(vertices[indices[i + 2]]),
|
||||
.color = Vector(1, 0, 0),
|
||||
});
|
||||
|
||||
verts.add(DebugVertex{
|
||||
.position = Vector(vertices[indices[i + 0]]),
|
||||
.color = Vector(1, 0, 0),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
#pragma once
|
||||
#include "Containers/Array.h"
|
||||
#include "Transform.h"
|
||||
#include "Graphics/DebugVertex.h"
|
||||
#include "Transform.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Component
|
||||
{
|
||||
struct ShapeBase
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
namespace Component {
|
||||
struct ShapeBase {
|
||||
ShapeBase();
|
||||
ShapeBase(Array<Vector> vertices, Array<uint32> indices);
|
||||
ShapeBase transform(const Component::Transform& transform) const;
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
#pragma once
|
||||
#include "Graphics/Texture.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Component
|
||||
{
|
||||
struct Skybox
|
||||
{
|
||||
namespace Seele {
|
||||
namespace Component {
|
||||
struct Skybox {
|
||||
Gfx::PTextureCube day;
|
||||
Gfx::PTextureCube night;
|
||||
Vector fogColor;
|
||||
|
||||
@@ -4,29 +4,11 @@ using namespace Seele::Component;
|
||||
|
||||
DEFINE_COMPONENT(Transform);
|
||||
|
||||
void Transform::setPosition(Vector pos)
|
||||
{
|
||||
transform.setPosition(pos);
|
||||
}
|
||||
void Transform::setPosition(Vector pos) { transform.setPosition(pos); }
|
||||
|
||||
void Transform::setRotation(Quaternion quat)
|
||||
{
|
||||
transform.setRotation(quat);
|
||||
}
|
||||
void Transform::setRotation(Quaternion quat) { transform.setRotation(quat); }
|
||||
|
||||
void Transform::setScale(Vector scale)
|
||||
{
|
||||
transform.setScale(scale);
|
||||
}
|
||||
void Transform::translate(Vector direction)
|
||||
{
|
||||
transform.setPosition(transform.getPosition() + direction);
|
||||
}
|
||||
void Transform::rotate(Quaternion quat)
|
||||
{
|
||||
transform.setRotation(transform.getRotation() * quat);
|
||||
}
|
||||
void Transform::scale(Vector scale)
|
||||
{
|
||||
transform.setScale(transform.getScale() + scale);
|
||||
}
|
||||
void Transform::setScale(Vector scale) { transform.setScale(scale); }
|
||||
void Transform::translate(Vector direction) { transform.setPosition(transform.getPosition() + direction); }
|
||||
void Transform::rotate(Quaternion quat) { transform.setRotation(transform.getRotation() * quat); }
|
||||
void Transform::scale(Vector scale) { transform.setScale(transform.getScale() + scale); }
|
||||
@@ -1,13 +1,11 @@
|
||||
#pragma once
|
||||
#include "Math/Transform.h"
|
||||
#include "Component.h"
|
||||
#include "Math/Transform.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Component
|
||||
{
|
||||
struct Transform
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
namespace Component {
|
||||
struct Transform {
|
||||
Vector getPosition() const { return transform.getPosition(); }
|
||||
Quaternion getRotation() const { return transform.getRotation(); }
|
||||
Vector getScale() const { return transform.getScale(); }
|
||||
@@ -24,7 +22,8 @@ struct Transform
|
||||
void translate(Vector direction);
|
||||
void rotate(Quaternion quat);
|
||||
void scale(Vector scale);
|
||||
private:
|
||||
|
||||
private:
|
||||
Math::Transform transform;
|
||||
};
|
||||
DECLARE_COMPONENT(Transform)
|
||||
|
||||
+6
-13
@@ -1,19 +1,12 @@
|
||||
#pragma once
|
||||
#include <concepts>
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
template<class F, class... Args>
|
||||
namespace Seele {
|
||||
template <class F, class... Args>
|
||||
concept invocable = std::invocable<F, Args...>;
|
||||
|
||||
template<class Archive, class T>
|
||||
concept serializable = requires(const T& t, Archive& a)
|
||||
{
|
||||
t.save(a);
|
||||
} && requires(T& t, Archive& a)
|
||||
{
|
||||
t.load(a);
|
||||
};
|
||||
template<typename T>
|
||||
template <class Archive, class T>
|
||||
concept serializable = requires(const T& t, Archive& a) { t.save(a); } && requires(T& t, Archive& a) { t.load(a); };
|
||||
template <typename T>
|
||||
concept enumeration = std::is_enum_v<T>;
|
||||
}
|
||||
} // namespace Seele
|
||||
+205
-498
File diff suppressed because it is too large
Load Diff
+109
-276
@@ -1,124 +1,77 @@
|
||||
#pragma once
|
||||
#include <memory_resource>
|
||||
#include <assert.h>
|
||||
#include <memory_resource>
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>>
|
||||
class List
|
||||
{
|
||||
private:
|
||||
struct Node
|
||||
{
|
||||
Node(Node* prev, Node* next, const T& data)
|
||||
: prev(prev)
|
||||
, next(next)
|
||||
, data(data)
|
||||
{}
|
||||
Node(Node* prev, Node* next, T&& data)
|
||||
: prev(prev)
|
||||
, next(next)
|
||||
, data(std::move(data))
|
||||
{}
|
||||
Node *prev;
|
||||
Node *next;
|
||||
|
||||
namespace Seele {
|
||||
template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> class List {
|
||||
private:
|
||||
struct Node {
|
||||
Node(Node* prev, Node* next, const T& data) : prev(prev), next(next), data(data) {}
|
||||
Node(Node* prev, Node* next, T&& data) : prev(prev), next(next), data(std::move(data)) {}
|
||||
Node* prev;
|
||||
Node* next;
|
||||
T data;
|
||||
};
|
||||
using NodeAllocator = std::allocator_traits<Allocator>::template rebind_alloc<Node>;
|
||||
|
||||
public:
|
||||
template <typename X>
|
||||
class IteratorBase
|
||||
{
|
||||
public:
|
||||
public:
|
||||
template <typename X> class IteratorBase {
|
||||
public:
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using value_type = X;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using reference = X&;
|
||||
using pointer = X*;
|
||||
|
||||
IteratorBase(Node *x = nullptr)
|
||||
: node(x)
|
||||
{
|
||||
}
|
||||
IteratorBase(const IteratorBase &i)
|
||||
: node(i.node)
|
||||
{
|
||||
}
|
||||
IteratorBase(IteratorBase&& i) noexcept
|
||||
: node(std::move(i.node))
|
||||
{
|
||||
}
|
||||
~IteratorBase()
|
||||
{
|
||||
}
|
||||
IteratorBase& operator=(const IteratorBase& other)
|
||||
{
|
||||
if(this != &other)
|
||||
{
|
||||
IteratorBase(Node* x = nullptr) : node(x) {}
|
||||
IteratorBase(const IteratorBase& i) : node(i.node) {}
|
||||
IteratorBase(IteratorBase&& i) noexcept : node(std::move(i.node)) {}
|
||||
~IteratorBase() {}
|
||||
IteratorBase& operator=(const IteratorBase& other) {
|
||||
if (this != &other) {
|
||||
node = other.node;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
IteratorBase& operator=(IteratorBase&& other) noexcept
|
||||
{
|
||||
if(this != &other)
|
||||
{
|
||||
IteratorBase& operator=(IteratorBase&& other) noexcept {
|
||||
if (this != &other) {
|
||||
node = std::move(other.node);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
constexpr reference operator*() const
|
||||
{
|
||||
return node->data;
|
||||
}
|
||||
constexpr pointer operator->() const
|
||||
{
|
||||
return &node->data;
|
||||
}
|
||||
constexpr bool operator!=(const IteratorBase &other)
|
||||
{
|
||||
return node != other.node;
|
||||
}
|
||||
constexpr bool operator==(const IteratorBase &other)
|
||||
{
|
||||
return node == other.node;
|
||||
}
|
||||
constexpr std::strong_ordering operator<=>(const IteratorBase& other)
|
||||
{
|
||||
return node <=> other.node;
|
||||
}
|
||||
constexpr IteratorBase &operator--()
|
||||
{
|
||||
constexpr reference operator*() const { return node->data; }
|
||||
constexpr pointer operator->() const { return &node->data; }
|
||||
constexpr bool operator!=(const IteratorBase& other) { return node != other.node; }
|
||||
constexpr bool operator==(const IteratorBase& other) { return node == other.node; }
|
||||
constexpr std::strong_ordering operator<=>(const IteratorBase& other) { return node <=> other.node; }
|
||||
constexpr IteratorBase& operator--() {
|
||||
node = node->prev;
|
||||
return *this;
|
||||
}
|
||||
constexpr IteratorBase operator--(int)
|
||||
{
|
||||
constexpr IteratorBase operator--(int) {
|
||||
IteratorBase tmp(*this);
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
constexpr IteratorBase &operator++()
|
||||
{
|
||||
constexpr IteratorBase& operator++() {
|
||||
node = node->next;
|
||||
return *this;
|
||||
}
|
||||
constexpr IteratorBase operator++(int)
|
||||
{
|
||||
constexpr IteratorBase operator++(int) {
|
||||
IteratorBase tmp(*this);
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
private:
|
||||
Node *node;
|
||||
private:
|
||||
Node* node;
|
||||
friend class List<T>;
|
||||
};
|
||||
|
||||
|
||||
using Iterator = IteratorBase<T>;
|
||||
using ConstIterator = IteratorBase<const T>;
|
||||
|
||||
|
||||
using value_type = T;
|
||||
using allocator_type = Allocator;
|
||||
using size_type = std::size_t;
|
||||
@@ -132,118 +85,72 @@ public:
|
||||
using const_iterator = ConstIterator;
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
|
||||
constexpr List()
|
||||
: allocator(Allocator())
|
||||
, root(allocateNode())
|
||||
, tail(root)
|
||||
, beginIt(Iterator(root))
|
||||
, endIt(Iterator(tail))
|
||||
, _size(0)
|
||||
{
|
||||
}
|
||||
|
||||
constexpr List() : allocator(Allocator()), root(allocateNode()), tail(root), beginIt(Iterator(root)), endIt(Iterator(tail)), _size(0) {}
|
||||
constexpr explicit List(const Allocator& alloc)
|
||||
: allocator(alloc)
|
||||
, root(allocateNode())
|
||||
, tail(root)
|
||||
, beginIt(Iterator(root))
|
||||
, endIt(Iterator(tail))
|
||||
, _size(0)
|
||||
{
|
||||
}
|
||||
constexpr List(size_type count, const T& value = T(), const Allocator& alloc = Allocator())
|
||||
: List(alloc)
|
||||
{
|
||||
for(size_type i = 0; i < count; ++i)
|
||||
{
|
||||
: allocator(alloc), root(allocateNode()), tail(root), beginIt(Iterator(root)), endIt(Iterator(tail)), _size(0) {}
|
||||
constexpr List(size_type count, const T& value = T(), const Allocator& alloc = Allocator()) : List(alloc) {
|
||||
for (size_type i = 0; i < count; ++i) {
|
||||
add(value);
|
||||
}
|
||||
}
|
||||
constexpr List(size_type count, const Allocator& alloc = Allocator())
|
||||
: List(alloc)
|
||||
{
|
||||
for(size_type i = 0; i < count; ++i)
|
||||
{
|
||||
constexpr List(size_type count, const Allocator& alloc = Allocator()) : List(alloc) {
|
||||
for (size_type i = 0; i < count; ++i) {
|
||||
add(T());
|
||||
}
|
||||
}
|
||||
constexpr List(const List& other)
|
||||
: List(std::allocator_traits<allocator_type>::select_on_container_copy_construction(other.allocator))
|
||||
{
|
||||
//TODO: improve
|
||||
for(const auto& it : other)
|
||||
{
|
||||
: List(std::allocator_traits<allocator_type>::select_on_container_copy_construction(other.allocator)) {
|
||||
// TODO: improve
|
||||
for (const auto& it : other) {
|
||||
add(it);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr List(const List& other, const Allocator& alloc)
|
||||
: List(alloc)
|
||||
{
|
||||
//TODO: improve
|
||||
for(const auto& it : other)
|
||||
{
|
||||
|
||||
constexpr List(const List& other, const Allocator& alloc) : List(alloc) {
|
||||
// TODO: improve
|
||||
for (const auto& it : other) {
|
||||
add(it);
|
||||
}
|
||||
}
|
||||
constexpr List(List&& other)
|
||||
: allocator(std::move(other.allocator))
|
||||
, root(std::move(other.root))
|
||||
, tail(std::move(other.tail))
|
||||
, beginIt(std::move(other.beginIt))
|
||||
, endIt(std::move(other.endIt))
|
||||
, _size(std::move(other._size))
|
||||
{
|
||||
: allocator(std::move(other.allocator)), root(std::move(other.root)), tail(std::move(other.tail)),
|
||||
beginIt(std::move(other.beginIt)), endIt(std::move(other.endIt)), _size(std::move(other._size)) {
|
||||
other.root = nullptr;
|
||||
other.tail = nullptr;
|
||||
other._size = 0;
|
||||
}
|
||||
constexpr List(List&& other, const Allocator& alloc)
|
||||
: allocator(alloc)
|
||||
, root(std::move(other.root))
|
||||
, tail(std::move(other.tail))
|
||||
, beginIt(std::move(other.beginIt))
|
||||
, endIt(std::move(other.endIt))
|
||||
, _size(std::move(other._size))
|
||||
{
|
||||
: allocator(alloc), root(std::move(other.root)), tail(std::move(other.tail)), beginIt(std::move(other.beginIt)),
|
||||
endIt(std::move(other.endIt)), _size(std::move(other._size)) {
|
||||
other.root = nullptr;
|
||||
other.tail = nullptr;
|
||||
other._size = 0;
|
||||
}
|
||||
constexpr ~List()
|
||||
{
|
||||
constexpr ~List() {
|
||||
clear();
|
||||
deallocateNode(tail);
|
||||
}
|
||||
constexpr List& operator=(const List& other)
|
||||
{
|
||||
if(this != &other)
|
||||
{
|
||||
constexpr List& operator=(const List& other) {
|
||||
if (this != &other) {
|
||||
clear();
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value )
|
||||
{
|
||||
if (!std::allocator_traits<allocator_type>::is_always_equal::value
|
||||
&& allocator != other.allocator)
|
||||
{
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value) {
|
||||
if (!std::allocator_traits<allocator_type>::is_always_equal::value && allocator != other.allocator) {
|
||||
clear();
|
||||
}
|
||||
allocator = other.allocator;
|
||||
}
|
||||
for(const auto& it : other)
|
||||
{
|
||||
for (const auto& it : other) {
|
||||
add(it);
|
||||
}
|
||||
markIteratorDirty();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
constexpr List& operator=(List&& other)
|
||||
{
|
||||
if(this != &other)
|
||||
{
|
||||
constexpr List& operator=(List&& other) {
|
||||
if (this != &other) {
|
||||
clear();
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value)
|
||||
{
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value) {
|
||||
allocator = std::move(other.allocator);
|
||||
}
|
||||
root = other.root;
|
||||
@@ -258,23 +165,14 @@ public:
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr reference front()
|
||||
{
|
||||
return root->data;
|
||||
}
|
||||
constexpr reference back()
|
||||
{
|
||||
return tail->prev->data;
|
||||
}
|
||||
constexpr void clear()
|
||||
{
|
||||
if (empty())
|
||||
{
|
||||
|
||||
constexpr reference front() { return root->data; }
|
||||
constexpr reference back() { return tail->prev->data; }
|
||||
constexpr void clear() {
|
||||
if (empty()) {
|
||||
return;
|
||||
}
|
||||
for (Node *tmp = root; tmp != tail;)
|
||||
{
|
||||
for (Node* tmp = root; tmp != tail;) {
|
||||
tmp = tmp->next;
|
||||
destroyNode(tmp->prev);
|
||||
deallocateNode(tmp->prev);
|
||||
@@ -283,24 +181,12 @@ public:
|
||||
markIteratorDirty();
|
||||
_size = 0;
|
||||
}
|
||||
//Insert at the end
|
||||
constexpr iterator add(const T &value)
|
||||
{
|
||||
return addInternal(value);
|
||||
}
|
||||
constexpr iterator add(T&& value)
|
||||
{
|
||||
return addInternal(std::move(value));
|
||||
}
|
||||
template<typename... args>
|
||||
constexpr reference emplace(args... arguments)
|
||||
{
|
||||
std::allocator_traits<NodeAllocator>::construct(allocator,
|
||||
tail,
|
||||
tail->prev,
|
||||
tail->next,
|
||||
arguments...);
|
||||
Node *newTail = allocateNode();
|
||||
// Insert at the end
|
||||
constexpr iterator add(const T& value) { return addInternal(value); }
|
||||
constexpr iterator add(T&& value) { return addInternal(std::move(value)); }
|
||||
template <typename... args> constexpr reference emplace(args... arguments) {
|
||||
std::allocator_traits<NodeAllocator>::construct(allocator, tail, tail->prev, tail->next, arguments...);
|
||||
Node* newTail = allocateNode();
|
||||
newTail->prev = tail;
|
||||
newTail->next = nullptr;
|
||||
tail->next = newTail;
|
||||
@@ -311,31 +197,23 @@ public:
|
||||
return insertedElement;
|
||||
}
|
||||
// front + popFront
|
||||
constexpr value_type retrieve()
|
||||
{
|
||||
constexpr value_type retrieve() {
|
||||
value_type temp = std::move(root->data);
|
||||
popFront();
|
||||
return temp;
|
||||
}
|
||||
constexpr iterator remove(iterator pos)
|
||||
{
|
||||
constexpr iterator remove(iterator pos) {
|
||||
_size--;
|
||||
Node *prev = pos.node->prev;
|
||||
Node *next = pos.node->next;
|
||||
if (prev == nullptr)
|
||||
{
|
||||
Node* prev = pos.node->prev;
|
||||
Node* next = pos.node->next;
|
||||
if (prev == nullptr) {
|
||||
root = next;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
prev->next = next;
|
||||
}
|
||||
if(next == nullptr)
|
||||
{
|
||||
if (next == nullptr) {
|
||||
tail = prev;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
next->prev = prev;
|
||||
}
|
||||
destroyNode(pos.node);
|
||||
@@ -343,111 +221,67 @@ public:
|
||||
markIteratorDirty();
|
||||
return Iterator(next);
|
||||
}
|
||||
constexpr void popBack()
|
||||
{
|
||||
constexpr void popBack() {
|
||||
assert(_size > 0);
|
||||
remove(Iterator(tail->prev));
|
||||
}
|
||||
constexpr void pop_back()
|
||||
{
|
||||
constexpr void pop_back() {
|
||||
assert(_size > 0);
|
||||
remove(Iterator(tail->prev));
|
||||
}
|
||||
constexpr void popFront()
|
||||
{
|
||||
constexpr void popFront() {
|
||||
assert(_size > 0);
|
||||
remove(Iterator(root));
|
||||
}
|
||||
constexpr void pop_front()
|
||||
{
|
||||
constexpr void pop_front() {
|
||||
assert(_size > 0);
|
||||
remove(Iterator(root));
|
||||
}
|
||||
constexpr iterator insert(iterator pos, const T &value)
|
||||
{
|
||||
constexpr iterator insert(iterator pos, const T& value) {
|
||||
_size++;
|
||||
Node *newNode = allocateNode();
|
||||
Node* newNode = allocateNode();
|
||||
initializeNode(newNode, value);
|
||||
newNode->next = pos.node;
|
||||
pos.node->prev = newNode;
|
||||
Node *tmp = pos.node->prev;
|
||||
if (tmp != nullptr)
|
||||
{
|
||||
Node* tmp = pos.node->prev;
|
||||
if (tmp != nullptr) {
|
||||
tmp->next = newNode;
|
||||
newNode->prev = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
root = newNode;
|
||||
}
|
||||
markIteratorDirty();
|
||||
return Iterator(newNode);
|
||||
}
|
||||
constexpr iterator find(const T &value)
|
||||
{
|
||||
for (Node *i = root; i != tail; i = i->next)
|
||||
{
|
||||
if (!(i->data < value) && !(value < i->data))
|
||||
{
|
||||
constexpr iterator find(const T& value) {
|
||||
for (Node* i = root; i != tail; i = i->next) {
|
||||
if (!(i->data < value) && !(value < i->data)) {
|
||||
return iterator(i);
|
||||
}
|
||||
}
|
||||
return endIt;
|
||||
}
|
||||
constexpr bool empty() const
|
||||
{
|
||||
return _size == 0;
|
||||
}
|
||||
constexpr size_type size() const
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
constexpr iterator begin()
|
||||
{
|
||||
return beginIt;
|
||||
}
|
||||
constexpr const_iterator begin() const
|
||||
{
|
||||
return cbeginIt;
|
||||
}
|
||||
constexpr iterator end()
|
||||
{
|
||||
return endIt;
|
||||
}
|
||||
constexpr const_iterator end() const
|
||||
{
|
||||
return cendIt;
|
||||
}
|
||||
constexpr bool empty() const { return _size == 0; }
|
||||
constexpr size_type size() const { return _size; }
|
||||
constexpr iterator begin() { return beginIt; }
|
||||
constexpr const_iterator begin() const { return cbeginIt; }
|
||||
constexpr iterator end() { return endIt; }
|
||||
constexpr const_iterator end() const { return cendIt; }
|
||||
|
||||
private:
|
||||
constexpr Node* allocateNode()
|
||||
{
|
||||
private:
|
||||
constexpr Node* allocateNode() {
|
||||
Node* node = allocator.allocate(1);
|
||||
assert(node != nullptr);
|
||||
node->prev = nullptr;
|
||||
node->next = nullptr;
|
||||
return node;
|
||||
}
|
||||
template<typename Type>
|
||||
constexpr void initializeNode(Node* node, Type&& data)
|
||||
{
|
||||
std::allocator_traits<NodeAllocator>::construct(allocator,
|
||||
node,
|
||||
node->prev,
|
||||
node->next,
|
||||
std::forward<Type>(data));
|
||||
template <typename Type> constexpr void initializeNode(Node* node, Type&& data) {
|
||||
std::allocator_traits<NodeAllocator>::construct(allocator, node, node->prev, node->next, std::forward<Type>(data));
|
||||
}
|
||||
constexpr void destroyNode(Node* node)
|
||||
{
|
||||
std::allocator_traits<NodeAllocator>::destroy(allocator, node);
|
||||
}
|
||||
constexpr void deallocateNode(Node* node)
|
||||
{
|
||||
allocator.deallocate(node, 1);
|
||||
}
|
||||
template<typename ValueType>
|
||||
constexpr iterator addInternal(ValueType&& value)
|
||||
{
|
||||
constexpr void destroyNode(Node* node) { std::allocator_traits<NodeAllocator>::destroy(allocator, node); }
|
||||
constexpr void deallocateNode(Node* node) { allocator.deallocate(node, 1); }
|
||||
template <typename ValueType> constexpr iterator addInternal(ValueType&& value) {
|
||||
initializeNode(tail, std::forward<ValueType>(value));
|
||||
Node* newTail = allocateNode();
|
||||
newTail->prev = tail;
|
||||
@@ -459,16 +293,15 @@ private:
|
||||
_size++;
|
||||
return insertedElement;
|
||||
}
|
||||
constexpr void markIteratorDirty()
|
||||
{
|
||||
constexpr void markIteratorDirty() {
|
||||
beginIt = Iterator(root);
|
||||
endIt = Iterator(tail);
|
||||
cbeginIt = ConstIterator(root);
|
||||
cendIt = ConstIterator(tail);
|
||||
}
|
||||
NodeAllocator allocator;
|
||||
Node *root;
|
||||
Node *tail;
|
||||
Node* root;
|
||||
Node* tail;
|
||||
iterator beginIt;
|
||||
iterator endIt;
|
||||
const_iterator cbeginIt;
|
||||
|
||||
+27
-78
@@ -1,26 +1,17 @@
|
||||
#pragma once
|
||||
#include <utility>
|
||||
#include "Array.h"
|
||||
#include "Pair.h"
|
||||
#include "Tree.h"
|
||||
#include "Serialization/Serialization.h"
|
||||
#include "Tree.h"
|
||||
#include <utility>
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
template<typename KeyType, typename PairType>
|
||||
struct _KeyFun
|
||||
{
|
||||
const KeyType& operator()(const PairType& pair) const
|
||||
{
|
||||
return pair.key;
|
||||
}
|
||||
|
||||
namespace Seele {
|
||||
template <typename KeyType, typename PairType> struct _KeyFun {
|
||||
const KeyType& operator()(const PairType& pair) const { return pair.key; }
|
||||
};
|
||||
template <typename K,
|
||||
typename V,
|
||||
typename Compare = std::less<K>,
|
||||
typename Allocator = std::pmr::polymorphic_allocator<Pair<const K, V>>>
|
||||
struct Map : public Tree<K, Pair<K, V>, _KeyFun<K, Pair<K, V>>, Compare, Allocator>
|
||||
{
|
||||
template <typename K, typename V, typename Compare = std::less<K>, typename Allocator = std::pmr::polymorphic_allocator<Pair<const K, V>>>
|
||||
struct Map : public Tree<K, Pair<K, V>, _KeyFun<K, Pair<K, V>>, Compare, Allocator> {
|
||||
using Super = Tree<K, Pair<K, V>, _KeyFun<K, Pair<K, V>>, Compare, Allocator>;
|
||||
using key_type = Super::key_type;
|
||||
using mapped_type = V;
|
||||
@@ -39,84 +30,42 @@ struct Map : public Tree<K, Pair<K, V>, _KeyFun<K, Pair<K, V>>, Compare, Allocat
|
||||
using reverse_iterator = Super::reverse_iterator;
|
||||
using const_reverse_iterator = Super::const_reverse_iterator;
|
||||
|
||||
constexpr Map() noexcept
|
||||
: Super()
|
||||
{
|
||||
}
|
||||
constexpr Map() noexcept : Super() {}
|
||||
constexpr explicit Map(const Compare& comp, const Allocator& alloc = Allocator()) noexcept(noexcept(Allocator()))
|
||||
: Super(comp, alloc)
|
||||
{
|
||||
}
|
||||
constexpr explicit Map(const Allocator& alloc) noexcept(noexcept(Compare()))
|
||||
: Super(alloc)
|
||||
{
|
||||
}
|
||||
constexpr mapped_type& operator[](const key_type& key)
|
||||
{
|
||||
: Super(comp, alloc) {}
|
||||
constexpr explicit Map(const Allocator& alloc) noexcept(noexcept(Compare())) : Super(alloc) {}
|
||||
constexpr mapped_type& operator[](const key_type& key) {
|
||||
auto [it, inserted] = Super::insert(Pair<K, V>(key, V()));
|
||||
return it->value;
|
||||
}
|
||||
constexpr const mapped_type& operator[](const key_type& key) const
|
||||
{
|
||||
return Super::find(key)->value;
|
||||
}
|
||||
constexpr mapped_type& at(const key_type& key)
|
||||
{
|
||||
constexpr const mapped_type& operator[](const key_type& key) const { return Super::find(key)->value; }
|
||||
constexpr mapped_type& at(const key_type& key) {
|
||||
iterator elem = Super::find(key);
|
||||
if (elem == Super::end())
|
||||
{
|
||||
if (elem == Super::end()) {
|
||||
throw std::logic_error("Key not found");
|
||||
}
|
||||
return elem->value;
|
||||
}
|
||||
constexpr const mapped_type& at(const key_type& key) const
|
||||
{
|
||||
return Super::find(key)->value;
|
||||
}
|
||||
constexpr iterator find(const key_type& key)
|
||||
{
|
||||
return Super::find(key);
|
||||
}
|
||||
constexpr iterator erase(const key_type& key)
|
||||
{
|
||||
return Super::remove(key);
|
||||
}
|
||||
constexpr bool exists(const key_type& key) const
|
||||
{
|
||||
return Super::find(key) != Super::end();
|
||||
}
|
||||
constexpr bool exists(const key_type& key)
|
||||
{
|
||||
return Super::find(key) != Super::end();
|
||||
}
|
||||
constexpr bool contains(const key_type& key) const
|
||||
{
|
||||
return exists(key);
|
||||
}
|
||||
constexpr bool contains(const key_type& key)
|
||||
{
|
||||
return exists(key);
|
||||
}
|
||||
constexpr Pair<iterator, bool> insert(const value_type& val)
|
||||
{
|
||||
return Super::insert(val);
|
||||
}
|
||||
void save(ArchiveBuffer& buffer) const
|
||||
{
|
||||
constexpr const mapped_type& at(const key_type& key) const { return Super::find(key)->value; }
|
||||
constexpr iterator find(const key_type& key) { return Super::find(key); }
|
||||
constexpr iterator erase(const key_type& key) { return Super::remove(key); }
|
||||
constexpr bool exists(const key_type& key) const { return Super::find(key) != Super::end(); }
|
||||
constexpr bool exists(const key_type& key) { return Super::find(key) != Super::end(); }
|
||||
constexpr bool contains(const key_type& key) const { return exists(key); }
|
||||
constexpr bool contains(const key_type& key) { return exists(key); }
|
||||
constexpr Pair<iterator, bool> insert(const value_type& val) { return Super::insert(val); }
|
||||
void save(ArchiveBuffer& buffer) const {
|
||||
size_t s = Super::size();
|
||||
buffer.writeBytes(&s, sizeof(uint64));
|
||||
for(const auto& [k, v] : *this)
|
||||
{
|
||||
for (const auto& [k, v] : *this) {
|
||||
Serialization::save(buffer, k);
|
||||
Serialization::save(buffer, v);
|
||||
}
|
||||
}
|
||||
void load(ArchiveBuffer& buffer)
|
||||
{
|
||||
void load(ArchiveBuffer& buffer) {
|
||||
uint64 len = 0;
|
||||
buffer.readBytes(&len, sizeof(uint64));
|
||||
for(uint64 i = 0; i < len; ++i)
|
||||
{
|
||||
for (uint64 i = 0; i < len; ++i) {
|
||||
K k = K();
|
||||
V v = V();
|
||||
Serialization::load(buffer, k);
|
||||
|
||||
@@ -1,30 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
template <typename K, typename V>
|
||||
struct Pair
|
||||
{
|
||||
public:
|
||||
constexpr Pair()
|
||||
: key(K()), value(V())
|
||||
{}
|
||||
constexpr Pair(const K & key, const V & value)
|
||||
: key(key), value(value)
|
||||
{}
|
||||
template<class U1 = K, class U2 = V>
|
||||
constexpr Pair(U1&& x, U2&& y)
|
||||
: key(std::forward<U1>(x))
|
||||
, value(std::forward<U2>(y))
|
||||
{
|
||||
}
|
||||
namespace Seele {
|
||||
template <typename K, typename V> struct Pair {
|
||||
public:
|
||||
constexpr Pair() : key(K()), value(V()) {}
|
||||
constexpr Pair(const K& key, const V& value) : key(key), value(value) {}
|
||||
template <class U1 = K, class U2 = V> constexpr Pair(U1&& x, U2&& y) : key(std::forward<U1>(x)), value(std::forward<U2>(y)) {}
|
||||
Pair(const Pair& other) = default;
|
||||
Pair(Pair&& other) = default;
|
||||
~Pair(){}
|
||||
~Pair() {}
|
||||
Pair& operator=(const Pair& other) = default;
|
||||
Pair& operator=(Pair&& other) = default;
|
||||
constexpr friend bool operator<(const Pair& left, const Pair& right)
|
||||
{
|
||||
constexpr friend bool operator<(const Pair& left, const Pair& right) {
|
||||
return left.key < right.key || (!(right.key < left.key) && left.value < right.value);
|
||||
}
|
||||
K key;
|
||||
|
||||
+10
-23
@@ -1,14 +1,13 @@
|
||||
#pragma once
|
||||
#include <utility>
|
||||
#include "Array.h"
|
||||
#include "Tree.h"
|
||||
#include <utility>
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
template<class Key, class Compare = std::less<Key>, class Allocator = std::pmr::polymorphic_allocator<Key>>
|
||||
class Set : public Tree<Key, Key, std::identity, Compare, Allocator>
|
||||
{
|
||||
public:
|
||||
|
||||
namespace Seele {
|
||||
template <class Key, class Compare = std::less<Key>, class Allocator = std::pmr::polymorphic_allocator<Key>>
|
||||
class Set : public Tree<Key, Key, std::identity, Compare, Allocator> {
|
||||
public:
|
||||
using Super = Tree<Key, Key, std::identity, Compare, Allocator>;
|
||||
using key_type = Key;
|
||||
using value_type = Key;
|
||||
@@ -26,21 +25,9 @@ public:
|
||||
using reverse_iterator = Super::reverse_iterator;
|
||||
using const_reverse_iterator = Super::const_reverse_iterator;
|
||||
|
||||
Set()
|
||||
: Set(Compare())
|
||||
{
|
||||
}
|
||||
explicit Set(const Compare& comp, const Allocator alloc = Allocator())
|
||||
: Super(comp, alloc)
|
||||
{
|
||||
}
|
||||
explicit Set(const Allocator alloc)
|
||||
: Super(alloc)
|
||||
{
|
||||
}
|
||||
constexpr Pair<iterator, bool> insert(const value_type& value)
|
||||
{
|
||||
return Super::insert(value);
|
||||
}
|
||||
Set() : Set(Compare()) {}
|
||||
explicit Set(const Compare& comp, const Allocator alloc = Allocator()) : Super(comp, alloc) {}
|
||||
explicit Set(const Allocator alloc) : Super(alloc) {}
|
||||
constexpr Pair<iterator, bool> insert(const value_type& value) { return Super::insert(value); }
|
||||
};
|
||||
} // namespace Seele
|
||||
+105
-276
@@ -1,147 +1,88 @@
|
||||
#pragma once
|
||||
#include <memory_resource>
|
||||
#include "Pair.h"
|
||||
#include <memory_resource>
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
template <
|
||||
typename KeyType,
|
||||
typename NodeData,
|
||||
typename KeyFun,
|
||||
typename Compare,
|
||||
typename Allocator>
|
||||
struct Tree
|
||||
{
|
||||
protected:
|
||||
struct Node
|
||||
{
|
||||
Node(Node* left, Node* right, const NodeData& nodeData)
|
||||
: leftChild(left)
|
||||
, rightChild(right)
|
||||
, data(nodeData)
|
||||
{}
|
||||
Node(Node* left, Node* right, NodeData&& nodeData)
|
||||
: leftChild(left)
|
||||
, rightChild(right)
|
||||
, data(std::move(nodeData))
|
||||
{}
|
||||
|
||||
namespace Seele {
|
||||
template <typename KeyType, typename NodeData, typename KeyFun, typename Compare, typename Allocator> struct Tree {
|
||||
protected:
|
||||
struct Node {
|
||||
Node(Node* left, Node* right, const NodeData& nodeData) : leftChild(left), rightChild(right), data(nodeData) {}
|
||||
Node(Node* left, Node* right, NodeData&& nodeData) : leftChild(left), rightChild(right), data(std::move(nodeData)) {}
|
||||
Node* leftChild;
|
||||
Node* rightChild;
|
||||
NodeData data;
|
||||
};
|
||||
using NodeAlloc = std::allocator_traits<Allocator>::template rebind_alloc<Node>;
|
||||
public:
|
||||
template<typename IterType>
|
||||
class IteratorBase
|
||||
{
|
||||
public:
|
||||
|
||||
public:
|
||||
template <typename IterType> class IteratorBase {
|
||||
public:
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
using value_type = IterType;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using reference = IterType&;
|
||||
using pointer = IterType*;
|
||||
|
||||
constexpr IteratorBase(Node* x = nullptr, Array<Node*>&& beginIt = Array<Node*>())
|
||||
: node(x), traversal(std::move(beginIt))
|
||||
{
|
||||
}
|
||||
constexpr IteratorBase(const IteratorBase& i)
|
||||
: node(i.node), traversal(i.traversal)
|
||||
{
|
||||
}
|
||||
constexpr IteratorBase(IteratorBase&& i) noexcept
|
||||
: node(std::move(i.node)), traversal(std::move(i.traversal))
|
||||
{
|
||||
}
|
||||
constexpr IteratorBase& operator=(const IteratorBase& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
constexpr IteratorBase(Node* x = nullptr, Array<Node*>&& beginIt = Array<Node*>()) : node(x), traversal(std::move(beginIt)) {}
|
||||
constexpr IteratorBase(const IteratorBase& i) : node(i.node), traversal(i.traversal) {}
|
||||
constexpr IteratorBase(IteratorBase&& i) noexcept : node(std::move(i.node)), traversal(std::move(i.traversal)) {}
|
||||
constexpr IteratorBase& operator=(const IteratorBase& other) {
|
||||
if (this != &other) {
|
||||
node = other.node;
|
||||
traversal = other.traversal;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
constexpr IteratorBase& operator=(IteratorBase&& other) noexcept
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
constexpr IteratorBase& operator=(IteratorBase&& other) noexcept {
|
||||
if (this != &other) {
|
||||
node = std::move(other.node);
|
||||
traversal = std::move(other.traversal);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
constexpr reference operator*() const
|
||||
{
|
||||
return node->data;
|
||||
}
|
||||
constexpr pointer operator->() const
|
||||
{
|
||||
return &(node->data);
|
||||
}
|
||||
constexpr bool operator!=(const IteratorBase& other)
|
||||
{
|
||||
return node != other.node;
|
||||
}
|
||||
constexpr bool operator==(const IteratorBase& other)
|
||||
{
|
||||
return node == other.node;
|
||||
}
|
||||
constexpr std::strong_ordering operator<=>(const IteratorBase& other)
|
||||
{
|
||||
return node <=> other.node;
|
||||
}
|
||||
constexpr IteratorBase& operator++()
|
||||
{
|
||||
constexpr reference operator*() const { return node->data; }
|
||||
constexpr pointer operator->() const { return &(node->data); }
|
||||
constexpr bool operator!=(const IteratorBase& other) { return node != other.node; }
|
||||
constexpr bool operator==(const IteratorBase& other) { return node == other.node; }
|
||||
constexpr std::strong_ordering operator<=>(const IteratorBase& other) { return node <=> other.node; }
|
||||
constexpr IteratorBase& operator++() {
|
||||
node = node->rightChild;
|
||||
while (node != nullptr
|
||||
&& node->leftChild != nullptr)
|
||||
{
|
||||
while (node != nullptr && node->leftChild != nullptr) {
|
||||
traversal.add(node);
|
||||
node = node->leftChild;
|
||||
}
|
||||
if (node == nullptr
|
||||
&& traversal.size() > 0)
|
||||
{
|
||||
if (node == nullptr && traversal.size() > 0) {
|
||||
node = traversal.back();
|
||||
traversal.pop();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
constexpr IteratorBase& operator--()
|
||||
{
|
||||
constexpr IteratorBase& operator--() {
|
||||
node = node->leftChild;
|
||||
while (node != nullptr
|
||||
&& node->rightChild != nullptr)
|
||||
{
|
||||
while (node != nullptr && node->rightChild != nullptr) {
|
||||
traversal.add(node);
|
||||
node = node->rightchild;
|
||||
}
|
||||
if (node == nullptr
|
||||
&& traversal.size() > 0)
|
||||
{
|
||||
if (node == nullptr && traversal.size() > 0) {
|
||||
node = traversal.back();
|
||||
traversal.pop();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
constexpr IteratorBase operator--(int)
|
||||
{
|
||||
constexpr IteratorBase operator--(int) {
|
||||
IteratorBase tmp(*this);
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
constexpr IteratorBase operator++(int)
|
||||
{
|
||||
constexpr IteratorBase operator++(int) {
|
||||
IteratorBase tmp(*this);
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
Node* getNode()
|
||||
{
|
||||
return node;
|
||||
}
|
||||
private:
|
||||
Node* getNode() { return node; }
|
||||
|
||||
private:
|
||||
Node* node;
|
||||
Array<Node*> traversal;
|
||||
};
|
||||
@@ -164,84 +105,39 @@ public:
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
|
||||
constexpr Tree() noexcept
|
||||
: alloc(NodeAlloc())
|
||||
, root(nullptr)
|
||||
, beginIt(nullptr)
|
||||
, endIt(nullptr)
|
||||
, iteratorsDirty(true)
|
||||
, _size(0)
|
||||
, comp(Compare())
|
||||
{
|
||||
}
|
||||
: alloc(NodeAlloc()), root(nullptr), beginIt(nullptr), endIt(nullptr), iteratorsDirty(true), _size(0), comp(Compare()) {}
|
||||
constexpr explicit Tree(const Compare& comp, const Allocator& alloc = Allocator()) noexcept(noexcept(Allocator()))
|
||||
: alloc(alloc)
|
||||
, root(nullptr)
|
||||
, beginIt(nullptr)
|
||||
, endIt(nullptr)
|
||||
, iteratorsDirty(true)
|
||||
, _size(0)
|
||||
, comp(comp)
|
||||
{
|
||||
}
|
||||
: alloc(alloc), root(nullptr), beginIt(nullptr), endIt(nullptr), iteratorsDirty(true), _size(0), comp(comp) {}
|
||||
constexpr explicit Tree(const Allocator& alloc) noexcept(noexcept(Compare()))
|
||||
: alloc(alloc)
|
||||
, root(nullptr)
|
||||
, beginIt(nullptr)
|
||||
, endIt(nullptr)
|
||||
, iteratorsDirty(true)
|
||||
, _size(0)
|
||||
, comp(Compare())
|
||||
{
|
||||
}
|
||||
constexpr Tree(const Tree& other)
|
||||
: alloc(other.alloc)
|
||||
, root(nullptr)
|
||||
, iteratorsDirty(true)
|
||||
, _size()
|
||||
, comp(other.comp)
|
||||
{
|
||||
for (const auto& elem : other)
|
||||
{
|
||||
: alloc(alloc), root(nullptr), beginIt(nullptr), endIt(nullptr), iteratorsDirty(true), _size(0), comp(Compare()) {}
|
||||
constexpr Tree(const Tree& other) : alloc(other.alloc), root(nullptr), iteratorsDirty(true), _size(), comp(other.comp) {
|
||||
for (const auto& elem : other) {
|
||||
insert(elem);
|
||||
}
|
||||
}
|
||||
constexpr Tree(Tree&& other) noexcept
|
||||
: alloc(std::move(other.alloc))
|
||||
, root(std::move(other.root))
|
||||
, iteratorsDirty(true)
|
||||
, _size(std::move(other._size))
|
||||
, comp(std::move(other.comp))
|
||||
{
|
||||
: alloc(std::move(other.alloc)), root(std::move(other.root)), iteratorsDirty(true), _size(std::move(other._size)),
|
||||
comp(std::move(other.comp)) {
|
||||
other._size = 0;
|
||||
}
|
||||
constexpr ~Tree() noexcept
|
||||
{
|
||||
clear();
|
||||
}
|
||||
constexpr Tree& operator=(const Tree& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
constexpr ~Tree() noexcept { clear(); }
|
||||
constexpr Tree& operator=(const Tree& other) {
|
||||
if (this != &other) {
|
||||
clear();
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value)
|
||||
{
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value) {
|
||||
alloc = other.alloc;
|
||||
}
|
||||
for (const auto& elem : other)
|
||||
{
|
||||
for (const auto& elem : other) {
|
||||
insert(elem);
|
||||
}
|
||||
markIteratorsDirty();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
constexpr Tree& operator=(Tree&& other) noexcept
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
constexpr Tree& operator=(Tree&& other) noexcept {
|
||||
if (this != &other) {
|
||||
clear();
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value)
|
||||
{
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value) {
|
||||
alloc = std::move(other.alloc);
|
||||
}
|
||||
root = std::move(other.root);
|
||||
@@ -252,144 +148,108 @@ public:
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
constexpr void clear()
|
||||
{
|
||||
while (_size > 0)
|
||||
{
|
||||
constexpr void clear() {
|
||||
while (_size > 0) {
|
||||
root = _remove(root, keyFun(root->data));
|
||||
}
|
||||
root = nullptr;
|
||||
markIteratorsDirty();
|
||||
}
|
||||
constexpr iterator begin()
|
||||
{
|
||||
if (iteratorsDirty)
|
||||
{
|
||||
constexpr iterator begin() {
|
||||
if (iteratorsDirty) {
|
||||
refreshIterators();
|
||||
}
|
||||
return beginIt;
|
||||
}
|
||||
constexpr iterator end()
|
||||
{
|
||||
if (iteratorsDirty)
|
||||
{
|
||||
constexpr iterator end() {
|
||||
if (iteratorsDirty) {
|
||||
refreshIterators();
|
||||
}
|
||||
return endIt;
|
||||
}
|
||||
constexpr iterator begin() const
|
||||
{
|
||||
if (iteratorsDirty)
|
||||
{
|
||||
constexpr iterator begin() const {
|
||||
if (iteratorsDirty) {
|
||||
return calcBeginIterator();
|
||||
}
|
||||
return beginIt;
|
||||
}
|
||||
constexpr iterator end() const
|
||||
{
|
||||
if (iteratorsDirty)
|
||||
{
|
||||
constexpr iterator end() const {
|
||||
if (iteratorsDirty) {
|
||||
return calcEndIterator();
|
||||
}
|
||||
return endIt;
|
||||
}
|
||||
constexpr bool empty() const
|
||||
{
|
||||
return _size == 0;
|
||||
}
|
||||
constexpr size_type size() const
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
protected:
|
||||
constexpr iterator find(const key_type& key)
|
||||
{
|
||||
constexpr bool empty() const { return _size == 0; }
|
||||
constexpr size_type size() const { return _size; }
|
||||
|
||||
protected:
|
||||
constexpr iterator find(const key_type& key) {
|
||||
root = _splay(root, key);
|
||||
if (root == nullptr || !equal(root->data, key))
|
||||
{
|
||||
if (root == nullptr || !equal(root->data, key)) {
|
||||
return end();
|
||||
}
|
||||
return iterator(root);
|
||||
}
|
||||
constexpr iterator find(const key_type& key) const
|
||||
{
|
||||
constexpr iterator find(const key_type& key) const {
|
||||
Node* it = root;
|
||||
while (it != nullptr && !equal(it->data, key))
|
||||
{
|
||||
if (comp(key, keyFun(it->data)))
|
||||
{
|
||||
while (it != nullptr && !equal(it->data, key)) {
|
||||
if (comp(key, keyFun(it->data))) {
|
||||
it = it->leftChild;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
it = it->rightChild;
|
||||
}
|
||||
}
|
||||
if (it == nullptr)
|
||||
{
|
||||
if (it == nullptr) {
|
||||
return end();
|
||||
}
|
||||
return iterator(it);
|
||||
}
|
||||
constexpr Pair<iterator, bool> insert(const NodeData& data)
|
||||
{
|
||||
constexpr Pair<iterator, bool> insert(const NodeData& data) {
|
||||
auto [r, inserted] = _insert(root, data);
|
||||
root = r;
|
||||
return Pair<iterator, bool>(iterator(root), inserted);
|
||||
}
|
||||
constexpr Pair<iterator, bool> insert(NodeData&& data)
|
||||
{
|
||||
constexpr Pair<iterator, bool> insert(NodeData&& data) {
|
||||
auto [r, inserted] = _insert(root, std::move(data));
|
||||
root = r;
|
||||
return Pair<iterator, bool>(iterator(root), inserted);
|
||||
}
|
||||
constexpr iterator remove(const key_type& key)
|
||||
{
|
||||
constexpr iterator remove(const key_type& key) {
|
||||
root = _remove(root, key);
|
||||
return iterator(root);
|
||||
}
|
||||
private:
|
||||
void verifyTree()
|
||||
{
|
||||
|
||||
private:
|
||||
void verifyTree() {
|
||||
size_t numElems = 0;
|
||||
for (const auto& it : *this)
|
||||
{
|
||||
for (const auto& it : *this) {
|
||||
numElems++;
|
||||
}
|
||||
assert(numElems == _size);
|
||||
}
|
||||
void markIteratorsDirty()
|
||||
{
|
||||
iteratorsDirty = true;
|
||||
}
|
||||
void refreshIterators()
|
||||
{
|
||||
void markIteratorsDirty() { iteratorsDirty = true; }
|
||||
void refreshIterators() {
|
||||
beginIt = calcBeginIterator();
|
||||
endIt = calcEndIterator();
|
||||
iteratorsDirty = false;
|
||||
}
|
||||
constexpr Iterator calcBeginIterator() const
|
||||
{
|
||||
constexpr Iterator calcBeginIterator() const {
|
||||
Node* begin = root;
|
||||
Array<Node*> beginTraversal;
|
||||
while (begin != nullptr)
|
||||
{
|
||||
while (begin != nullptr) {
|
||||
beginTraversal.add(begin);
|
||||
begin = begin->leftChild;
|
||||
}
|
||||
if (!beginTraversal.empty())
|
||||
{
|
||||
if (!beginTraversal.empty()) {
|
||||
begin = beginTraversal.back();
|
||||
beginTraversal.pop();
|
||||
}
|
||||
return Iterator(begin, std::move(beginTraversal));
|
||||
}
|
||||
constexpr Iterator calcEndIterator() const
|
||||
{
|
||||
constexpr Iterator calcEndIterator() const {
|
||||
Node* endIndex = root;
|
||||
Array<Node*> endTraversal;
|
||||
while (endIndex != nullptr)
|
||||
{
|
||||
while (endIndex != nullptr) {
|
||||
endTraversal.add(endIndex);
|
||||
endIndex = endIndex->rightChild;
|
||||
}
|
||||
@@ -403,26 +263,21 @@ private:
|
||||
size_type _size;
|
||||
Compare comp;
|
||||
KeyFun keyFun = KeyFun();
|
||||
Node* rotateLeft(Node* x)
|
||||
{
|
||||
Node* rotateLeft(Node* x) {
|
||||
Node* y = x->rightChild;
|
||||
x->rightChild = y->leftChild;
|
||||
y->leftChild = x;
|
||||
return y;
|
||||
}
|
||||
Node* rotateRight(Node* x)
|
||||
{
|
||||
Node* rotateRight(Node* x) {
|
||||
Node* y = x->leftChild;
|
||||
x->leftChild = y->rightChild;
|
||||
y->rightChild = x;
|
||||
return y;
|
||||
}
|
||||
template<class NodeDataType>
|
||||
Pair<Node*, bool> _insert(Node* r, NodeDataType&& data)
|
||||
{
|
||||
template <class NodeDataType> Pair<Node*, bool> _insert(Node* r, NodeDataType&& data) {
|
||||
markIteratorsDirty();
|
||||
if (r == nullptr)
|
||||
{
|
||||
if (r == nullptr) {
|
||||
root = alloc.allocate(1);
|
||||
std::allocator_traits<NodeAlloc>::construct(alloc, root, nullptr, nullptr, std::forward<NodeDataType>(data));
|
||||
_size++;
|
||||
@@ -436,14 +291,11 @@ private:
|
||||
Node* newNode = alloc.allocate(1);
|
||||
std::allocator_traits<NodeAlloc>::construct(alloc, newNode, nullptr, nullptr, std::forward<NodeDataType>(data));
|
||||
|
||||
if (comp(keyFun(newNode->data), keyFun(r->data)))
|
||||
{
|
||||
if (comp(keyFun(newNode->data), keyFun(r->data))) {
|
||||
newNode->rightChild = r;
|
||||
newNode->leftChild = r->leftChild;
|
||||
r->leftChild = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
newNode->leftChild = r;
|
||||
newNode->rightChild = r->rightChild;
|
||||
r->rightChild = nullptr;
|
||||
@@ -451,9 +303,7 @@ private:
|
||||
_size++;
|
||||
return Pair<Node*, bool>(newNode, true);
|
||||
}
|
||||
template<class K>
|
||||
Node* _remove(Node* r, K&& key)
|
||||
{
|
||||
template <class K> Node* _remove(Node* r, K&& key) {
|
||||
markIteratorsDirty();
|
||||
Node* temp;
|
||||
if (r == nullptr)
|
||||
@@ -464,13 +314,10 @@ private:
|
||||
if (!equal(r->data, key))
|
||||
return r;
|
||||
|
||||
if (r->leftChild == nullptr)
|
||||
{
|
||||
if (r->leftChild == nullptr) {
|
||||
temp = r;
|
||||
r = r->rightChild;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
temp = r;
|
||||
|
||||
r = _splay(r->leftChild, key);
|
||||
@@ -481,52 +328,38 @@ private:
|
||||
_size--;
|
||||
return r;
|
||||
}
|
||||
template<class K>
|
||||
Node* _splay(Node* r, K&& key)
|
||||
{
|
||||
template <class K> Node* _splay(Node* r, K&& key) {
|
||||
markIteratorsDirty();
|
||||
if (r == nullptr || equal(r->data, key))
|
||||
{
|
||||
if (r == nullptr || equal(r->data, key)) {
|
||||
return r;
|
||||
}
|
||||
if (comp(key, keyFun(r->data)))
|
||||
{
|
||||
if (comp(key, keyFun(r->data))) {
|
||||
if (r->leftChild == nullptr)
|
||||
return r;
|
||||
|
||||
if (comp(key, keyFun(r->leftChild->data)))
|
||||
{
|
||||
if (comp(key, keyFun(r->leftChild->data))) {
|
||||
r->leftChild->leftChild = _splay(r->leftChild->leftChild, key);
|
||||
|
||||
r = rotateRight(r);
|
||||
}
|
||||
else if (comp(keyFun(r->leftChild->data), key))
|
||||
{
|
||||
} else if (comp(keyFun(r->leftChild->data), key)) {
|
||||
r->leftChild->rightChild = _splay(r->leftChild->rightChild, key);
|
||||
|
||||
if (r->leftChild->rightChild != nullptr)
|
||||
{
|
||||
if (r->leftChild->rightChild != nullptr) {
|
||||
r->leftChild = rotateLeft(r->leftChild);
|
||||
}
|
||||
}
|
||||
return (r->leftChild == nullptr) ? r : rotateRight(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (r->rightChild == nullptr)
|
||||
return r;
|
||||
|
||||
if (comp(key, keyFun(r->rightChild->data)))
|
||||
{
|
||||
if (comp(key, keyFun(r->rightChild->data))) {
|
||||
r->rightChild->leftChild = _splay(r->rightChild->leftChild, key);
|
||||
|
||||
if (r->rightChild->leftChild != nullptr)
|
||||
{
|
||||
if (r->rightChild->leftChild != nullptr) {
|
||||
r->rightChild = rotateRight(r->rightChild);
|
||||
}
|
||||
}
|
||||
else if (comp(keyFun(r->rightChild->data), key))
|
||||
{
|
||||
} else if (comp(keyFun(r->rightChild->data), key)) {
|
||||
r->rightChild->rightChild = _splay(r->rightChild->rightChild, key);
|
||||
|
||||
r = rotateLeft(r);
|
||||
@@ -534,10 +367,6 @@ private:
|
||||
return (r->rightChild == nullptr) ? r : rotateLeft(r);
|
||||
}
|
||||
}
|
||||
template<typename K>
|
||||
bool equal(const NodeData& a, K&& b) const
|
||||
{
|
||||
return !comp(keyFun(a), b) && !comp(b, keyFun(a));
|
||||
}
|
||||
template <typename K> bool equal(const NodeData& a, K&& b) const { return !comp(keyFun(a), b) && !comp(b, keyFun(a)); }
|
||||
};
|
||||
} // namespace Seele
|
||||
+3
-5
@@ -2,11 +2,9 @@
|
||||
#include "Scene/Scene.h"
|
||||
#include "System/SystemGraph.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class Game
|
||||
{
|
||||
public:
|
||||
namespace Seele {
|
||||
class Game {
|
||||
public:
|
||||
Game() {}
|
||||
virtual ~Game() {}
|
||||
virtual void setupScene(PScene scene, PSystemGraph graph) = 0;
|
||||
|
||||
@@ -3,60 +3,34 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
Buffer::Buffer(QueueFamilyMapping mapping, QueueType startQueue)
|
||||
: QueueOwnedResource(mapping, startQueue)
|
||||
{
|
||||
}
|
||||
Buffer::Buffer(QueueFamilyMapping mapping, QueueType startQueue) : QueueOwnedResource(mapping, startQueue) {}
|
||||
|
||||
Buffer::~Buffer()
|
||||
{
|
||||
}
|
||||
Buffer::~Buffer() {}
|
||||
|
||||
VertexBuffer::VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType)
|
||||
: Buffer(mapping, startQueueType)
|
||||
, numVertices(numVertices)
|
||||
, vertexSize(vertexSize)
|
||||
{
|
||||
}
|
||||
VertexBuffer::~VertexBuffer()
|
||||
{
|
||||
}
|
||||
: Buffer(mapping, startQueueType), numVertices(numVertices), vertexSize(vertexSize) {}
|
||||
VertexBuffer::~VertexBuffer() {}
|
||||
|
||||
IndexBuffer::IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType indexType, QueueType startQueueType)
|
||||
: Buffer(mapping, startQueueType)
|
||||
, indexType(indexType)
|
||||
{
|
||||
switch (indexType)
|
||||
{
|
||||
case SE_INDEX_TYPE_UINT16:
|
||||
numIndices = size / sizeof(uint16);
|
||||
break;
|
||||
case SE_INDEX_TYPE_UINT32:
|
||||
numIndices = size / sizeof(uint32);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
IndexBuffer::~IndexBuffer()
|
||||
{
|
||||
: Buffer(mapping, startQueueType), indexType(indexType) {
|
||||
switch (indexType) {
|
||||
case SE_INDEX_TYPE_UINT16:
|
||||
numIndices = size / sizeof(uint16);
|
||||
break;
|
||||
case SE_INDEX_TYPE_UINT32:
|
||||
numIndices = size / sizeof(uint32);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
IndexBuffer::~IndexBuffer() {}
|
||||
|
||||
UniformBuffer::UniformBuffer(QueueFamilyMapping mapping, const DataSource& sourceData)
|
||||
: Buffer(mapping, sourceData.owner)
|
||||
{}
|
||||
UniformBuffer::UniformBuffer(QueueFamilyMapping mapping, const DataSource& sourceData) : Buffer(mapping, sourceData.owner) {}
|
||||
|
||||
UniformBuffer::~UniformBuffer()
|
||||
{
|
||||
}
|
||||
UniformBuffer::~UniformBuffer() {}
|
||||
|
||||
ShaderBuffer::ShaderBuffer(QueueFamilyMapping mapping, uint32 numElements, const DataSource& sourceData)
|
||||
: Buffer(mapping, sourceData.owner)
|
||||
, numElements(numElements)
|
||||
{
|
||||
}
|
||||
|
||||
ShaderBuffer::~ShaderBuffer()
|
||||
{
|
||||
}
|
||||
: Buffer(mapping, sourceData.owner), numElements(numElements) {}
|
||||
|
||||
ShaderBuffer::~ShaderBuffer() {}
|
||||
|
||||
@@ -1,106 +1,95 @@
|
||||
#pragma once
|
||||
#include "Resources.h"
|
||||
#include "Initializer.h"
|
||||
#include "Resources.h"
|
||||
|
||||
|
||||
namespace Seele {
|
||||
namespace Gfx {
|
||||
class Buffer : public QueueOwnedResource {
|
||||
public:
|
||||
Buffer(QueueFamilyMapping mapping, QueueType startQueueType);
|
||||
virtual ~Buffer();
|
||||
public:
|
||||
Buffer(QueueFamilyMapping mapping, QueueType startQueueType);
|
||||
virtual ~Buffer();
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
};
|
||||
|
||||
class VertexBuffer : public Buffer {
|
||||
public:
|
||||
VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices,
|
||||
uint32 vertexSize, QueueType startQueueType);
|
||||
virtual ~VertexBuffer();
|
||||
constexpr uint32 getNumVertices() const { return numVertices; }
|
||||
// Size of one vertex in bytes
|
||||
constexpr uint32 getVertexSize() const { return vertexSize; }
|
||||
public:
|
||||
VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType);
|
||||
virtual ~VertexBuffer();
|
||||
constexpr uint32 getNumVertices() const { return numVertices; }
|
||||
// Size of one vertex in bytes
|
||||
constexpr uint32 getVertexSize() const { return vertexSize; }
|
||||
|
||||
virtual void updateRegion(DataSource update) = 0;
|
||||
virtual void download(Array<uint8> &buffer) = 0;
|
||||
virtual void updateRegion(DataSource update) = 0;
|
||||
virtual void download(Array<uint8>& buffer) = 0;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess,
|
||||
SePipelineStageFlags srcStage,
|
||||
SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
uint32 numVertices;
|
||||
uint32 vertexSize;
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
uint32 numVertices;
|
||||
uint32 vertexSize;
|
||||
};
|
||||
DEFINE_REF(VertexBuffer)
|
||||
|
||||
class IndexBuffer : public Buffer {
|
||||
public:
|
||||
IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType index,
|
||||
QueueType startQueueType);
|
||||
virtual ~IndexBuffer();
|
||||
constexpr uint64 getNumIndices() const { return numIndices; }
|
||||
constexpr Gfx::SeIndexType getIndexType() const { return indexType; }
|
||||
public:
|
||||
IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType index, QueueType startQueueType);
|
||||
virtual ~IndexBuffer();
|
||||
constexpr uint64 getNumIndices() const { return numIndices; }
|
||||
constexpr Gfx::SeIndexType getIndexType() const { return indexType; }
|
||||
|
||||
virtual void download(Array<uint8> &buffer) = 0;
|
||||
virtual void download(Array<uint8>& buffer) = 0;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess,
|
||||
SePipelineStageFlags srcStage,
|
||||
SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
Gfx::SeIndexType indexType;
|
||||
uint64 numIndices;
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
Gfx::SeIndexType indexType;
|
||||
uint64 numIndices;
|
||||
};
|
||||
DEFINE_REF(IndexBuffer)
|
||||
|
||||
DECLARE_REF(UniformBuffer)
|
||||
class UniformBuffer : public Buffer {
|
||||
public:
|
||||
UniformBuffer(QueueFamilyMapping mapping, const DataSource &sourceData);
|
||||
virtual ~UniformBuffer();
|
||||
public:
|
||||
UniformBuffer(QueueFamilyMapping mapping, const DataSource& sourceData);
|
||||
virtual ~UniformBuffer();
|
||||
|
||||
virtual void rotateBuffer(uint64 size) = 0;
|
||||
virtual void updateContents(const DataSource &sourceData) = 0;
|
||||
virtual void rotateBuffer(uint64 size) = 0;
|
||||
virtual void updateContents(const DataSource& sourceData) = 0;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess,
|
||||
SePipelineStageFlags srcStage,
|
||||
SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
};
|
||||
DEFINE_REF(UniformBuffer)
|
||||
class ShaderBuffer : public Buffer {
|
||||
public:
|
||||
ShaderBuffer(QueueFamilyMapping mapping, uint32 numElements,
|
||||
const DataSource &bulkResourceData);
|
||||
virtual ~ShaderBuffer();
|
||||
virtual void rotateBuffer(uint64 size, bool preserveContents = false) = 0;
|
||||
virtual void updateContents(const ShaderBufferCreateInfo &sourceData) = 0;
|
||||
constexpr uint32 getNumElements() const { return numElements; }
|
||||
virtual void *mapRegion(uint64 offset = 0, uint64 size = -1,
|
||||
bool writeOnly = true) = 0;
|
||||
virtual void unmap() = 0;
|
||||
public:
|
||||
ShaderBuffer(QueueFamilyMapping mapping, uint32 numElements, const DataSource& bulkResourceData);
|
||||
virtual ~ShaderBuffer();
|
||||
virtual void rotateBuffer(uint64 size, bool preserveContents = false) = 0;
|
||||
virtual void updateContents(const ShaderBufferCreateInfo& sourceData) = 0;
|
||||
constexpr uint32 getNumElements() const { return numElements; }
|
||||
virtual void* mapRegion(uint64 offset = 0, uint64 size = -1, bool writeOnly = true) = 0;
|
||||
virtual void unmap() = 0;
|
||||
|
||||
virtual void clear() = 0;
|
||||
virtual void clear() = 0;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess,
|
||||
SePipelineStageFlags srcStage,
|
||||
SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
|
||||
uint32 numElements;
|
||||
uint32 numElements;
|
||||
};
|
||||
DEFINE_REF(ShaderBuffer)
|
||||
} // namespace Gfx
|
||||
|
||||
@@ -3,19 +3,10 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
RenderCommand::RenderCommand() {}
|
||||
|
||||
RenderCommand::RenderCommand()
|
||||
{
|
||||
}
|
||||
RenderCommand::~RenderCommand() {}
|
||||
|
||||
RenderCommand::~RenderCommand()
|
||||
{
|
||||
}
|
||||
ComputeCommand::ComputeCommand() {}
|
||||
|
||||
ComputeCommand::ComputeCommand()
|
||||
{
|
||||
}
|
||||
|
||||
ComputeCommand::~ComputeCommand()
|
||||
{
|
||||
}
|
||||
ComputeCommand::~ComputeCommand() {}
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
#pragma once
|
||||
#include "Enums.h"
|
||||
#include "Descriptor.h"
|
||||
#include "Enums.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
namespace Gfx {
|
||||
DECLARE_REF(Viewport)
|
||||
class RenderCommand
|
||||
{
|
||||
public:
|
||||
class RenderCommand {
|
||||
public:
|
||||
RenderCommand();
|
||||
virtual ~RenderCommand();
|
||||
virtual void setViewport(Gfx::PViewport viewport) = 0;
|
||||
@@ -26,9 +24,8 @@ public:
|
||||
std::string name;
|
||||
};
|
||||
DEFINE_REF(RenderCommand)
|
||||
class ComputeCommand
|
||||
{
|
||||
public:
|
||||
class ComputeCommand {
|
||||
public:
|
||||
ComputeCommand();
|
||||
virtual ~ComputeCommand();
|
||||
virtual void bindPipeline(Gfx::PComputePipeline pipeline) = 0;
|
||||
@@ -40,5 +37,5 @@ public:
|
||||
};
|
||||
DEFINE_REF(ComputeCommand)
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
@@ -1,11 +1,10 @@
|
||||
#pragma once
|
||||
#include "Math/Vector.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "Math/Vector.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
struct DebugVertex
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
struct DebugVertex {
|
||||
Vector position;
|
||||
Vector color;
|
||||
};
|
||||
|
||||
@@ -6,28 +6,28 @@ using namespace Seele::Gfx;
|
||||
DescriptorLayout::DescriptorLayout(const std::string& name) : name(name) {}
|
||||
|
||||
DescriptorLayout::DescriptorLayout(const DescriptorLayout& other) {
|
||||
descriptorBindings.resize(other.descriptorBindings.size());
|
||||
for (uint32 i = 0; i < descriptorBindings.size(); ++i) {
|
||||
descriptorBindings[i] = other.descriptorBindings[i];
|
||||
}
|
||||
descriptorBindings.resize(other.descriptorBindings.size());
|
||||
for (uint32 i = 0; i < descriptorBindings.size(); ++i) {
|
||||
descriptorBindings[i] = other.descriptorBindings[i];
|
||||
}
|
||||
}
|
||||
|
||||
DescriptorLayout& DescriptorLayout::operator=(const DescriptorLayout& other) {
|
||||
if (this != &other) {
|
||||
descriptorBindings.resize(other.descriptorBindings.size());
|
||||
for (uint32 i = 0; i < descriptorBindings.size(); ++i) {
|
||||
descriptorBindings[i] = other.descriptorBindings[i];
|
||||
if (this != &other) {
|
||||
descriptorBindings.resize(other.descriptorBindings.size());
|
||||
for (uint32 i = 0; i < descriptorBindings.size(); ++i) {
|
||||
descriptorBindings[i] = other.descriptorBindings[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DescriptorLayout::~DescriptorLayout() {}
|
||||
|
||||
void DescriptorLayout::addDescriptorBinding(DescriptorBinding binding) {
|
||||
if (descriptorBindings.size() <= binding.binding) {
|
||||
descriptorBindings.resize(binding.binding + 1);
|
||||
}
|
||||
if (descriptorBindings.size() <= binding.binding) {
|
||||
descriptorBindings.resize(binding.binding + 1);
|
||||
}
|
||||
descriptorBindings[binding.binding] = binding;
|
||||
}
|
||||
|
||||
@@ -45,27 +45,22 @@ DescriptorSet::~DescriptorSet() {}
|
||||
|
||||
PipelineLayout::PipelineLayout(const std::string& name) : name(name) {}
|
||||
|
||||
PipelineLayout::PipelineLayout(const std::string& name, PPipelineLayout baseLayout) : name(name){
|
||||
if (baseLayout != nullptr) {
|
||||
descriptorSetLayouts = baseLayout->descriptorSetLayouts;
|
||||
pushConstants = baseLayout->pushConstants;
|
||||
}
|
||||
PipelineLayout::PipelineLayout(const std::string& name, PPipelineLayout baseLayout) : name(name) {
|
||||
if (baseLayout != nullptr) {
|
||||
descriptorSetLayouts = baseLayout->descriptorSetLayouts;
|
||||
pushConstants = baseLayout->pushConstants;
|
||||
}
|
||||
}
|
||||
|
||||
PipelineLayout::~PipelineLayout() {}
|
||||
|
||||
void PipelineLayout::addDescriptorLayout(PDescriptorLayout layout) {
|
||||
descriptorSetLayouts[layout->getName()] = layout;
|
||||
}
|
||||
void PipelineLayout::addDescriptorLayout(PDescriptorLayout layout) { descriptorSetLayouts[layout->getName()] = layout; }
|
||||
|
||||
void PipelineLayout::addPushConstants(const SePushConstantRange& pushConstant) { pushConstants.add(pushConstant); }
|
||||
|
||||
void PipelineLayout::addMapping(Map<std::string, uint32> mapping)
|
||||
{
|
||||
for(const auto& [name, index] : mapping)
|
||||
{
|
||||
if(parameterMapping.contains(name))
|
||||
{
|
||||
void PipelineLayout::addMapping(Map<std::string, uint32> mapping) {
|
||||
for (const auto& [name, index] : mapping) {
|
||||
if (parameterMapping.contains(name)) {
|
||||
assert(parameterMapping[name] == index);
|
||||
}
|
||||
parameterMapping[name] = index;
|
||||
|
||||
@@ -1,55 +1,54 @@
|
||||
#pragma once
|
||||
#include "Enums.h"
|
||||
#include "Resources.h"
|
||||
#include "Initializer.h"
|
||||
#include "Resources.h"
|
||||
|
||||
|
||||
namespace Seele {
|
||||
namespace Gfx {
|
||||
struct DescriptorBinding {
|
||||
uint32 binding = 0;
|
||||
SeDescriptorType descriptorType = SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
SeImageViewType textureType = SE_IMAGE_VIEW_TYPE_2D;
|
||||
uint32 descriptorCount = 1;
|
||||
SeDescriptorBindingFlags bindingFlags = 0;
|
||||
SeShaderStageFlags shaderStages = SE_SHADER_STAGE_ALL;
|
||||
Gfx::SeDescriptorAccessTypeFlags access = SE_DESCRIPTOR_ACCESS_READ_ONLY_BIT;
|
||||
uint32 binding = 0;
|
||||
SeDescriptorType descriptorType = SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
SeImageViewType textureType = SE_IMAGE_VIEW_TYPE_2D;
|
||||
uint32 descriptorCount = 1;
|
||||
SeDescriptorBindingFlags bindingFlags = 0;
|
||||
SeShaderStageFlags shaderStages = SE_SHADER_STAGE_ALL;
|
||||
Gfx::SeDescriptorAccessTypeFlags access = SE_DESCRIPTOR_ACCESS_READ_ONLY_BIT;
|
||||
};
|
||||
|
||||
DECLARE_REF(DescriptorPool)
|
||||
DECLARE_REF(DescriptorSet)
|
||||
class DescriptorLayout {
|
||||
public:
|
||||
DescriptorLayout(const std::string &name);
|
||||
DescriptorLayout(const DescriptorLayout &other);
|
||||
DescriptorLayout &operator=(const DescriptorLayout &other);
|
||||
virtual ~DescriptorLayout();
|
||||
void addDescriptorBinding(DescriptorBinding binding);
|
||||
void reset();
|
||||
PDescriptorSet allocateDescriptorSet();
|
||||
virtual void create() = 0;
|
||||
constexpr const Array<DescriptorBinding> &getBindings() const {
|
||||
return descriptorBindings;
|
||||
}
|
||||
constexpr uint32 getHash() const { return hash; }
|
||||
constexpr const std::string &getName() const { return name; }
|
||||
public:
|
||||
DescriptorLayout(const std::string& name);
|
||||
DescriptorLayout(const DescriptorLayout& other);
|
||||
DescriptorLayout& operator=(const DescriptorLayout& other);
|
||||
virtual ~DescriptorLayout();
|
||||
void addDescriptorBinding(DescriptorBinding binding);
|
||||
void reset();
|
||||
PDescriptorSet allocateDescriptorSet();
|
||||
virtual void create() = 0;
|
||||
constexpr const Array<DescriptorBinding>& getBindings() const { return descriptorBindings; }
|
||||
constexpr uint32 getHash() const { return hash; }
|
||||
constexpr const std::string& getName() const { return name; }
|
||||
|
||||
protected:
|
||||
Array<DescriptorBinding> descriptorBindings;
|
||||
ODescriptorPool pool;
|
||||
std::string name;
|
||||
uint32 hash = 0;
|
||||
friend class PipelineLayout;
|
||||
friend class DescriptorPool;
|
||||
protected:
|
||||
Array<DescriptorBinding> descriptorBindings;
|
||||
ODescriptorPool pool;
|
||||
std::string name;
|
||||
uint32 hash = 0;
|
||||
friend class PipelineLayout;
|
||||
friend class DescriptorPool;
|
||||
};
|
||||
DEFINE_REF(DescriptorLayout)
|
||||
|
||||
DECLARE_REF(DescriptorSet)
|
||||
class DescriptorPool {
|
||||
public:
|
||||
DescriptorPool();
|
||||
virtual ~DescriptorPool();
|
||||
virtual PDescriptorSet allocateDescriptorSet() = 0;
|
||||
virtual void reset() = 0;
|
||||
public:
|
||||
DescriptorPool();
|
||||
virtual ~DescriptorPool();
|
||||
virtual PDescriptorSet allocateDescriptorSet() = 0;
|
||||
virtual void reset() = 0;
|
||||
};
|
||||
DEFINE_REF(DescriptorPool)
|
||||
DECLARE_REF(UniformBuffer)
|
||||
@@ -57,54 +56,47 @@ DECLARE_REF(ShaderBuffer)
|
||||
DECLARE_REF(Texture)
|
||||
DECLARE_REF(Sampler)
|
||||
class DescriptorSet {
|
||||
public:
|
||||
DescriptorSet(PDescriptorLayout layout);
|
||||
virtual ~DescriptorSet();
|
||||
virtual void writeChanges() = 0;
|
||||
virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0;
|
||||
virtual void updateBuffer(uint32 binding, PShaderBuffer ShaderBuffer) = 0;
|
||||
virtual void updateBuffer(uint32_t binding, uint32 index,
|
||||
Gfx::PShaderBuffer uniformBuffer) = 0;
|
||||
virtual void updateSampler(uint32 binding, PSampler sampler) = 0;
|
||||
virtual void updateTexture(uint32 binding, PTexture texture,
|
||||
PSampler samplerState = nullptr) = 0;
|
||||
virtual void updateTextureArray(uint32_t binding,
|
||||
Array<PTexture> texture) = 0;
|
||||
bool operator<(PDescriptorSet other);
|
||||
public:
|
||||
DescriptorSet(PDescriptorLayout layout);
|
||||
virtual ~DescriptorSet();
|
||||
virtual void writeChanges() = 0;
|
||||
virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0;
|
||||
virtual void updateBuffer(uint32 binding, PShaderBuffer ShaderBuffer) = 0;
|
||||
virtual void updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer uniformBuffer) = 0;
|
||||
virtual void updateSampler(uint32 binding, PSampler sampler) = 0;
|
||||
virtual void updateTexture(uint32 binding, PTexture texture, PSampler samplerState = nullptr) = 0;
|
||||
virtual void updateTextureArray(uint32_t binding, Array<PTexture> texture) = 0;
|
||||
bool operator<(PDescriptorSet other);
|
||||
|
||||
constexpr PDescriptorLayout getLayout() const { return layout; }
|
||||
constexpr const std::string &getName() const { return layout->getName(); }
|
||||
constexpr PDescriptorLayout getLayout() const { return layout; }
|
||||
constexpr const std::string& getName() const { return layout->getName(); }
|
||||
|
||||
protected:
|
||||
PDescriptorLayout layout;
|
||||
protected:
|
||||
PDescriptorLayout layout;
|
||||
};
|
||||
DEFINE_REF(DescriptorSet)
|
||||
|
||||
DECLARE_REF(PipelineLayout)
|
||||
class PipelineLayout {
|
||||
public:
|
||||
PipelineLayout(const std::string &name);
|
||||
PipelineLayout(const std::string &name, PPipelineLayout baseLayout);
|
||||
virtual ~PipelineLayout();
|
||||
virtual void create() = 0;
|
||||
void addDescriptorLayout(PDescriptorLayout layout);
|
||||
void addPushConstants(const SePushConstantRange &pushConstants);
|
||||
constexpr uint32 getHash() const { return layoutHash; }
|
||||
constexpr const Map<std::string, PDescriptorLayout> &getLayouts() const {
|
||||
return descriptorSetLayouts;
|
||||
}
|
||||
constexpr uint32 findParameter(const std::string ¶m) const {
|
||||
return parameterMapping[param];
|
||||
}
|
||||
void addMapping(Map<std::string, uint32> mapping);
|
||||
constexpr std::string getName() const { return name; };
|
||||
public:
|
||||
PipelineLayout(const std::string& name);
|
||||
PipelineLayout(const std::string& name, PPipelineLayout baseLayout);
|
||||
virtual ~PipelineLayout();
|
||||
virtual void create() = 0;
|
||||
void addDescriptorLayout(PDescriptorLayout layout);
|
||||
void addPushConstants(const SePushConstantRange& pushConstants);
|
||||
constexpr uint32 getHash() const { return layoutHash; }
|
||||
constexpr const Map<std::string, PDescriptorLayout>& getLayouts() const { return descriptorSetLayouts; }
|
||||
constexpr uint32 findParameter(const std::string& param) const { return parameterMapping[param]; }
|
||||
void addMapping(Map<std::string, uint32> mapping);
|
||||
constexpr std::string getName() const { return name; };
|
||||
|
||||
protected:
|
||||
uint32 layoutHash = 0;
|
||||
Map<std::string, PDescriptorLayout> descriptorSetLayouts;
|
||||
Map<std::string, uint32> parameterMapping;
|
||||
Array<SePushConstantRange> pushConstants;
|
||||
std::string name;
|
||||
protected:
|
||||
uint32 layoutHash = 0;
|
||||
Map<std::string, PDescriptorLayout> descriptorSetLayouts;
|
||||
Map<std::string, uint32> parameterMapping;
|
||||
Array<SePushConstantRange> pushConstants;
|
||||
std::string name;
|
||||
};
|
||||
DEFINE_REF(PipelineLayout)
|
||||
} // namespace Gfx
|
||||
|
||||
+107
-108
@@ -4,113 +4,112 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
FormatCompatibilityInfo Gfx::getFormatInfo(SeFormat format)
|
||||
{
|
||||
switch(format) {
|
||||
case SE_FORMAT_R4G4_UNORM_PACK8:
|
||||
case SE_FORMAT_R8_UNORM:
|
||||
case SE_FORMAT_R8_SNORM:
|
||||
case SE_FORMAT_R8_USCALED:
|
||||
case SE_FORMAT_R8_SSCALED:
|
||||
case SE_FORMAT_R8_UINT:
|
||||
case SE_FORMAT_R8_SINT:
|
||||
case SE_FORMAT_R8_SRGB:
|
||||
return FormatCompatibilityInfo {
|
||||
.blockSize = 1,
|
||||
.blockExtent = UVector(1, 1, 1),
|
||||
.texelsPerBlock = 1,
|
||||
};
|
||||
case SE_FORMAT_R10X6_UNORM_PACK16:
|
||||
case SE_FORMAT_R12X4_UNORM_PACK16:
|
||||
//case SE_FORMAT_A4R4G4B4_UNORM_PACK16:
|
||||
//case SE_FORMAT_A4B4G4R4_UNORM_PACK16:
|
||||
case SE_FORMAT_R4G4B4A4_UNORM_PACK16:
|
||||
case SE_FORMAT_B4G4R4A4_UNORM_PACK16:
|
||||
case SE_FORMAT_R5G6B5_UNORM_PACK16:
|
||||
case SE_FORMAT_B5G6R5_UNORM_PACK16:
|
||||
case SE_FORMAT_R5G5B5A1_UNORM_PACK16:
|
||||
case SE_FORMAT_B5G5R5A1_UNORM_PACK16:
|
||||
case SE_FORMAT_A1R5G5B5_UNORM_PACK16:
|
||||
case SE_FORMAT_R8G8_UNORM:
|
||||
case SE_FORMAT_R8G8_SNORM:
|
||||
case SE_FORMAT_R8G8_USCALED:
|
||||
case SE_FORMAT_R8G8_SSCALED:
|
||||
case SE_FORMAT_R8G8_UINT:
|
||||
case SE_FORMAT_R8G8_SINT:
|
||||
case SE_FORMAT_R8G8_SRGB:
|
||||
case SE_FORMAT_R16_UNORM:
|
||||
case SE_FORMAT_R16_SNORM:
|
||||
case SE_FORMAT_R16_USCALED:
|
||||
case SE_FORMAT_R16_SSCALED:
|
||||
case SE_FORMAT_R16_UINT:
|
||||
case SE_FORMAT_R16_SINT:
|
||||
case SE_FORMAT_R16_SFLOAT:
|
||||
return FormatCompatibilityInfo {
|
||||
.blockSize = 2,
|
||||
.blockExtent = UVector(1, 1, 1),
|
||||
.texelsPerBlock = 1,
|
||||
};
|
||||
case SE_FORMAT_BC7_UNORM_BLOCK:
|
||||
case SE_FORMAT_BC7_SRGB_BLOCK:
|
||||
return FormatCompatibilityInfo {
|
||||
.blockSize = 16,
|
||||
.blockExtent = UVector(4, 4, 1),
|
||||
.texelsPerBlock = 16,
|
||||
};
|
||||
case SE_FORMAT_R10X6G10X6_UNORM_2PACK16:
|
||||
case SE_FORMAT_R12X4G12X4_UNORM_2PACK16:
|
||||
//case SE_FORMAT_R16G16_S10_5_NV:
|
||||
case SE_FORMAT_R8G8B8A8_UNORM:
|
||||
case SE_FORMAT_R8G8B8A8_SNORM:
|
||||
case SE_FORMAT_R8G8B8A8_USCALED:
|
||||
case SE_FORMAT_R8G8B8A8_SSCALED:
|
||||
case SE_FORMAT_R8G8B8A8_UINT:
|
||||
case SE_FORMAT_R8G8B8A8_SINT:
|
||||
case SE_FORMAT_R8G8B8A8_SRGB:
|
||||
case SE_FORMAT_B8G8R8A8_UNORM:
|
||||
case SE_FORMAT_B8G8R8A8_SNORM:
|
||||
case SE_FORMAT_B8G8R8A8_USCALED:
|
||||
case SE_FORMAT_B8G8R8A8_SSCALED:
|
||||
case SE_FORMAT_B8G8R8A8_UINT:
|
||||
case SE_FORMAT_B8G8R8A8_SINT:
|
||||
case SE_FORMAT_B8G8R8A8_SRGB:
|
||||
case SE_FORMAT_A8B8G8R8_UNORM_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_SNORM_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_USCALED_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_SSCALED_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_UINT_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_SINT_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_SRGB_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_UNORM_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_SNORM_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_USCALED_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_SSCALED_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_UINT_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_SINT_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_UNORM_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_SNORM_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_USCALED_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_SSCALED_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_UINT_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_SINT_PACK32:
|
||||
case SE_FORMAT_R16G16_UNORM:
|
||||
case SE_FORMAT_R16G16_SNORM:
|
||||
case SE_FORMAT_R16G16_USCALED:
|
||||
case SE_FORMAT_R16G16_SSCALED:
|
||||
case SE_FORMAT_R16G16_UINT:
|
||||
case SE_FORMAT_R16G16_SINT:
|
||||
case SE_FORMAT_R16G16_SFLOAT:
|
||||
case SE_FORMAT_R32_UINT:
|
||||
case SE_FORMAT_R32_SINT:
|
||||
case SE_FORMAT_R32_SFLOAT:
|
||||
case SE_FORMAT_B10G11R11_UFLOAT_PACK32:
|
||||
case SE_FORMAT_E5B9G9R9_UFLOAT_PACK32:
|
||||
return FormatCompatibilityInfo{
|
||||
.blockSize = 4,
|
||||
.blockExtent = Vector(1, 1, 1),
|
||||
.texelsPerBlock = 1,
|
||||
};
|
||||
default:
|
||||
throw new std::logic_error("not yet implemented");
|
||||
FormatCompatibilityInfo Gfx::getFormatInfo(SeFormat format) {
|
||||
switch (format) {
|
||||
case SE_FORMAT_R4G4_UNORM_PACK8:
|
||||
case SE_FORMAT_R8_UNORM:
|
||||
case SE_FORMAT_R8_SNORM:
|
||||
case SE_FORMAT_R8_USCALED:
|
||||
case SE_FORMAT_R8_SSCALED:
|
||||
case SE_FORMAT_R8_UINT:
|
||||
case SE_FORMAT_R8_SINT:
|
||||
case SE_FORMAT_R8_SRGB:
|
||||
return FormatCompatibilityInfo{
|
||||
.blockSize = 1,
|
||||
.blockExtent = UVector(1, 1, 1),
|
||||
.texelsPerBlock = 1,
|
||||
};
|
||||
case SE_FORMAT_R10X6_UNORM_PACK16:
|
||||
case SE_FORMAT_R12X4_UNORM_PACK16:
|
||||
// case SE_FORMAT_A4R4G4B4_UNORM_PACK16:
|
||||
// case SE_FORMAT_A4B4G4R4_UNORM_PACK16:
|
||||
case SE_FORMAT_R4G4B4A4_UNORM_PACK16:
|
||||
case SE_FORMAT_B4G4R4A4_UNORM_PACK16:
|
||||
case SE_FORMAT_R5G6B5_UNORM_PACK16:
|
||||
case SE_FORMAT_B5G6R5_UNORM_PACK16:
|
||||
case SE_FORMAT_R5G5B5A1_UNORM_PACK16:
|
||||
case SE_FORMAT_B5G5R5A1_UNORM_PACK16:
|
||||
case SE_FORMAT_A1R5G5B5_UNORM_PACK16:
|
||||
case SE_FORMAT_R8G8_UNORM:
|
||||
case SE_FORMAT_R8G8_SNORM:
|
||||
case SE_FORMAT_R8G8_USCALED:
|
||||
case SE_FORMAT_R8G8_SSCALED:
|
||||
case SE_FORMAT_R8G8_UINT:
|
||||
case SE_FORMAT_R8G8_SINT:
|
||||
case SE_FORMAT_R8G8_SRGB:
|
||||
case SE_FORMAT_R16_UNORM:
|
||||
case SE_FORMAT_R16_SNORM:
|
||||
case SE_FORMAT_R16_USCALED:
|
||||
case SE_FORMAT_R16_SSCALED:
|
||||
case SE_FORMAT_R16_UINT:
|
||||
case SE_FORMAT_R16_SINT:
|
||||
case SE_FORMAT_R16_SFLOAT:
|
||||
return FormatCompatibilityInfo{
|
||||
.blockSize = 2,
|
||||
.blockExtent = UVector(1, 1, 1),
|
||||
.texelsPerBlock = 1,
|
||||
};
|
||||
case SE_FORMAT_BC7_UNORM_BLOCK:
|
||||
case SE_FORMAT_BC7_SRGB_BLOCK:
|
||||
return FormatCompatibilityInfo{
|
||||
.blockSize = 16,
|
||||
.blockExtent = UVector(4, 4, 1),
|
||||
.texelsPerBlock = 16,
|
||||
};
|
||||
case SE_FORMAT_R10X6G10X6_UNORM_2PACK16:
|
||||
case SE_FORMAT_R12X4G12X4_UNORM_2PACK16:
|
||||
// case SE_FORMAT_R16G16_S10_5_NV:
|
||||
case SE_FORMAT_R8G8B8A8_UNORM:
|
||||
case SE_FORMAT_R8G8B8A8_SNORM:
|
||||
case SE_FORMAT_R8G8B8A8_USCALED:
|
||||
case SE_FORMAT_R8G8B8A8_SSCALED:
|
||||
case SE_FORMAT_R8G8B8A8_UINT:
|
||||
case SE_FORMAT_R8G8B8A8_SINT:
|
||||
case SE_FORMAT_R8G8B8A8_SRGB:
|
||||
case SE_FORMAT_B8G8R8A8_UNORM:
|
||||
case SE_FORMAT_B8G8R8A8_SNORM:
|
||||
case SE_FORMAT_B8G8R8A8_USCALED:
|
||||
case SE_FORMAT_B8G8R8A8_SSCALED:
|
||||
case SE_FORMAT_B8G8R8A8_UINT:
|
||||
case SE_FORMAT_B8G8R8A8_SINT:
|
||||
case SE_FORMAT_B8G8R8A8_SRGB:
|
||||
case SE_FORMAT_A8B8G8R8_UNORM_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_SNORM_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_USCALED_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_SSCALED_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_UINT_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_SINT_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_SRGB_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_UNORM_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_SNORM_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_USCALED_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_SSCALED_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_UINT_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_SINT_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_UNORM_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_SNORM_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_USCALED_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_SSCALED_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_UINT_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_SINT_PACK32:
|
||||
case SE_FORMAT_R16G16_UNORM:
|
||||
case SE_FORMAT_R16G16_SNORM:
|
||||
case SE_FORMAT_R16G16_USCALED:
|
||||
case SE_FORMAT_R16G16_SSCALED:
|
||||
case SE_FORMAT_R16G16_UINT:
|
||||
case SE_FORMAT_R16G16_SINT:
|
||||
case SE_FORMAT_R16G16_SFLOAT:
|
||||
case SE_FORMAT_R32_UINT:
|
||||
case SE_FORMAT_R32_SINT:
|
||||
case SE_FORMAT_R32_SFLOAT:
|
||||
case SE_FORMAT_B10G11R11_UFLOAT_PACK32:
|
||||
case SE_FORMAT_E5B9G9R9_UFLOAT_PACK32:
|
||||
return FormatCompatibilityInfo{
|
||||
.blockSize = 4,
|
||||
.blockExtent = Vector(1, 1, 1),
|
||||
.texelsPerBlock = 1,
|
||||
};
|
||||
default:
|
||||
throw new std::logic_error("not yet implemented");
|
||||
}
|
||||
}
|
||||
|
||||
+238
-327
File diff suppressed because it is too large
Load Diff
@@ -1,14 +1,9 @@
|
||||
#include "Graphics.h"
|
||||
#include "Shader.h"
|
||||
#include "Graphics.h"
|
||||
|
||||
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
Graphics::Graphics()
|
||||
{
|
||||
shaderCompiler = new ShaderCompiler(this);
|
||||
}
|
||||
Graphics::Graphics() { shaderCompiler = new ShaderCompiler(this); }
|
||||
|
||||
Graphics::~Graphics()
|
||||
{
|
||||
}
|
||||
Graphics::~Graphics() {}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "Initializer.h"
|
||||
#include "Resources.h"
|
||||
#include "RenderTarget.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "Initializer.h"
|
||||
#include "MinimalEngine.h"
|
||||
#include "RenderTarget.h"
|
||||
#include "Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
namespace Gfx {
|
||||
DECLARE_REF(Window)
|
||||
DECLARE_REF(Viewport)
|
||||
DECLARE_REF(ShaderCompiler)
|
||||
@@ -33,25 +32,18 @@ DECLARE_REF(RenderCommand)
|
||||
DECLARE_REF(ComputeCommand)
|
||||
DECLARE_REF(BottomLevelAS)
|
||||
DECLARE_REF(TopLevelAS)
|
||||
class Graphics
|
||||
{
|
||||
public:
|
||||
class Graphics {
|
||||
public:
|
||||
Graphics();
|
||||
virtual ~Graphics();
|
||||
virtual void init(GraphicsInitializer initializer) = 0;
|
||||
|
||||
const QueueFamilyMapping getFamilyMapping() const
|
||||
{
|
||||
return queueMapping;
|
||||
}
|
||||
|
||||
PShaderCompiler getShaderCompiler()
|
||||
{
|
||||
return shaderCompiler;
|
||||
}
|
||||
|
||||
virtual OWindow createWindow(const WindowCreateInfo &createInfo) = 0;
|
||||
virtual OViewport createViewport(PWindow owner, const ViewportCreateInfo &createInfo) = 0;
|
||||
const QueueFamilyMapping getFamilyMapping() const { return queueMapping; }
|
||||
|
||||
PShaderCompiler getShaderCompiler() { return shaderCompiler; }
|
||||
|
||||
virtual OWindow createWindow(const WindowCreateInfo& createInfo) = 0;
|
||||
virtual OViewport createViewport(PWindow owner, const ViewportCreateInfo& createInfo) = 0;
|
||||
|
||||
virtual ORenderPass createRenderPass(RenderTargetLayout layout, Array<SubPassDependency> dependencies, PViewport renderArea) = 0;
|
||||
virtual void beginRenderPass(PRenderPass renderPass) = 0;
|
||||
@@ -61,17 +53,17 @@ public:
|
||||
virtual void executeCommands(Array<ORenderCommand> commands) = 0;
|
||||
virtual void executeCommands(Array<OComputeCommand> commands) = 0;
|
||||
|
||||
virtual OTexture2D createTexture2D(const TextureCreateInfo &createInfo) = 0;
|
||||
virtual OTexture3D createTexture3D(const TextureCreateInfo &createInfo) = 0;
|
||||
virtual OTextureCube createTextureCube(const TextureCreateInfo &createInfo) = 0;
|
||||
virtual OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) = 0;
|
||||
virtual OShaderBuffer createShaderBuffer(const ShaderBufferCreateInfo &bulkData) = 0;
|
||||
virtual OVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) = 0;
|
||||
virtual OIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) = 0;
|
||||
|
||||
virtual OTexture2D createTexture2D(const TextureCreateInfo& createInfo) = 0;
|
||||
virtual OTexture3D createTexture3D(const TextureCreateInfo& createInfo) = 0;
|
||||
virtual OTextureCube createTextureCube(const TextureCreateInfo& createInfo) = 0;
|
||||
virtual OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo& bulkData) = 0;
|
||||
virtual OShaderBuffer createShaderBuffer(const ShaderBufferCreateInfo& bulkData) = 0;
|
||||
virtual OVertexBuffer createVertexBuffer(const VertexBufferCreateInfo& bulkData) = 0;
|
||||
virtual OIndexBuffer createIndexBuffer(const IndexBufferCreateInfo& bulkData) = 0;
|
||||
|
||||
virtual ORenderCommand createRenderCommand(const std::string& name = "") = 0;
|
||||
virtual OComputeCommand createComputeCommand(const std::string& name = "") = 0;
|
||||
|
||||
|
||||
virtual OVertexShader createVertexShader(const ShaderCreateInfo& createInfo) = 0;
|
||||
virtual OFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) = 0;
|
||||
virtual OComputeShader createComputeShader(const ShaderCreateInfo& createInfo) = 0;
|
||||
@@ -82,8 +74,8 @@ public:
|
||||
virtual PComputePipeline createComputePipeline(ComputePipelineCreateInfo createInfo) = 0;
|
||||
virtual OSampler createSampler(const SamplerCreateInfo& createInfo) = 0;
|
||||
|
||||
virtual ODescriptorLayout createDescriptorLayout(const std::string& name = "") = 0;
|
||||
virtual OPipelineLayout createPipelineLayout(const std::string& name = "", PPipelineLayout baseLayout = nullptr) = 0;
|
||||
virtual ODescriptorLayout createDescriptorLayout(const std::string& name = "") = 0;
|
||||
virtual OPipelineLayout createPipelineLayout(const std::string& name = "", PPipelineLayout baseLayout = nullptr) = 0;
|
||||
|
||||
virtual OVertexInput createVertexInput(VertexInputStateCreateInfo createInfo) = 0;
|
||||
|
||||
@@ -94,7 +86,8 @@ public:
|
||||
// Ray Tracing
|
||||
virtual OBottomLevelAS createBottomLevelAccelerationStructure(const BottomLevelASCreateInfo& createInfo) = 0;
|
||||
virtual OTopLevelAS createTopLevelAccelerationStructure(const TopLevelASCreateInfo& createInfo) = 0;
|
||||
protected:
|
||||
|
||||
protected:
|
||||
QueueFamilyMapping queueMapping;
|
||||
OShaderCompiler shaderCompiler;
|
||||
bool meshShadingEnabled = false;
|
||||
|
||||
+223
-256
@@ -1,266 +1,233 @@
|
||||
#pragma once
|
||||
#include "Enums.h"
|
||||
#include "Containers/Map.h"
|
||||
#include "Enums.h"
|
||||
#include "Math/Math.h"
|
||||
#include "MinimalEngine.h"
|
||||
#include "MeshData.h"
|
||||
#include "MinimalEngine.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
struct GraphicsInitializer
|
||||
{
|
||||
const char* applicationName;
|
||||
const char* engineName;
|
||||
const char* windowLayoutFile;
|
||||
/**
|
||||
* layers defines the enabled Vulkan layers used in the instance,
|
||||
* if ENABLE_VALIDATION is defined, standard validation is already enabled
|
||||
* not yet implemented
|
||||
*/
|
||||
Array<const char*> layers;
|
||||
Array<const char*> instanceExtensions;
|
||||
Array<const char*> deviceExtensions;
|
||||
|
||||
void* windowHandle;
|
||||
GraphicsInitializer()
|
||||
: applicationName("SeeleEngine")
|
||||
, engineName("SeeleEngine")
|
||||
, windowLayoutFile(nullptr)
|
||||
, layers{ "VK_LAYER_LUNARG_monitor" }
|
||||
, instanceExtensions{}
|
||||
, deviceExtensions{ "VK_KHR_swapchain" }
|
||||
, windowHandle(nullptr)
|
||||
{
|
||||
}
|
||||
};
|
||||
struct WindowCreateInfo
|
||||
{
|
||||
int32 width;
|
||||
int32 height;
|
||||
const char* title;
|
||||
Gfx::SeFormat preferredFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM;
|
||||
void* windowHandle;
|
||||
};
|
||||
struct ViewportCreateInfo
|
||||
{
|
||||
URect dimensions;
|
||||
float fieldOfView = 1.222f; // 70 deg
|
||||
Gfx::SeSampleCountFlags numSamples;
|
||||
};
|
||||
// doesnt own the data, only proxy it
|
||||
struct DataSource
|
||||
{
|
||||
uint64 size = 0;
|
||||
uint64 offset = 0;
|
||||
uint8* data = nullptr;
|
||||
Gfx::QueueType owner = Gfx::QueueType::GRAPHICS;
|
||||
};
|
||||
struct TextureCreateInfo
|
||||
{
|
||||
DataSource sourceData = DataSource();
|
||||
Gfx::SeFormat format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT;
|
||||
uint32 width = 1;
|
||||
uint32 height = 1;
|
||||
uint32 depth = 1;
|
||||
uint32 mipLevels = 1;
|
||||
uint32 layers = 1;
|
||||
uint32 elements = 1;
|
||||
uint32 samples = 1;
|
||||
Gfx::SeImageUsageFlags usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT;
|
||||
Gfx::SeMemoryPropertyFlags memoryProps = Gfx::SE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
std::string name;
|
||||
};
|
||||
struct SamplerCreateInfo
|
||||
{
|
||||
Gfx::SeSamplerCreateFlags flags;
|
||||
Gfx::SeFilter magFilter = Gfx::SE_FILTER_LINEAR;
|
||||
Gfx::SeFilter minFilter = Gfx::SE_FILTER_LINEAR;
|
||||
Gfx::SeSamplerMipmapMode mipmapMode = Gfx::SE_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
Gfx::SeSamplerAddressMode addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
Gfx::SeSamplerAddressMode addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
Gfx::SeSamplerAddressMode addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
float mipLodBias = 0.0f;
|
||||
uint32 anisotropyEnable = 0;
|
||||
float maxAnisotropy = 0.0f;
|
||||
uint32 compareEnable = 0;
|
||||
Gfx::SeCompareOp compareOp = Gfx::SE_COMPARE_OP_NEVER;
|
||||
float minLod = 0.0f;
|
||||
float maxLod = 0.0f;
|
||||
Gfx::SeBorderColor borderColor = Gfx::SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
|
||||
uint32 unnormalizedCoordinates = 0;
|
||||
std::string name;
|
||||
};
|
||||
struct VertexBufferCreateInfo
|
||||
{
|
||||
DataSource sourceData = DataSource();
|
||||
// bytes per vertex
|
||||
uint32 vertexSize = 0;
|
||||
uint32 numVertices = 0;
|
||||
std::string name = "Unnamed";
|
||||
};
|
||||
struct IndexBufferCreateInfo
|
||||
{
|
||||
DataSource sourceData = DataSource();
|
||||
Gfx::SeIndexType indexType = Gfx::SeIndexType::SE_INDEX_TYPE_UINT16;
|
||||
std::string name = "Unnamed";
|
||||
};
|
||||
struct UniformBufferCreateInfo
|
||||
{
|
||||
DataSource sourceData = DataSource();
|
||||
uint8 dynamic = 0;
|
||||
std::string name = "Unnamed";
|
||||
};
|
||||
struct ShaderBufferCreateInfo
|
||||
{
|
||||
DataSource sourceData = DataSource();
|
||||
uint64 numElements = 1;
|
||||
uint8 dynamic = 0;
|
||||
uint8 vertexBuffer = 0;
|
||||
std::string name = "Unnamed";
|
||||
};
|
||||
DECLARE_NAME_REF(Gfx, PipelineLayout)
|
||||
struct ShaderCreateInfo
|
||||
{
|
||||
std::string name; // Debug info
|
||||
std::string mainModule;
|
||||
Array<std::string> additionalModules;
|
||||
std::string entryPoint;
|
||||
Array<Pair<const char*, const char*>> typeParameter;
|
||||
Map<const char*, const char*> defines;
|
||||
Gfx::PPipelineLayout rootSignature;
|
||||
};
|
||||
struct VertexInputBinding
|
||||
{
|
||||
uint32 binding;
|
||||
uint32 stride;
|
||||
Gfx::SeVertexInputRate inputRate;
|
||||
};
|
||||
struct VertexInputAttribute
|
||||
{
|
||||
uint32 location;
|
||||
uint32 binding;
|
||||
Gfx::SeFormat format;
|
||||
uint32 offset;
|
||||
};
|
||||
struct VertexInputStateCreateInfo
|
||||
{
|
||||
Array<VertexInputBinding> bindings;
|
||||
Array<VertexInputAttribute> attributes;
|
||||
};
|
||||
DECLARE_REF(MaterialInstance)
|
||||
namespace Gfx
|
||||
{
|
||||
struct SePushConstantRange
|
||||
{
|
||||
SeShaderStageFlags stageFlags;
|
||||
uint32 offset;
|
||||
uint32 size;
|
||||
};
|
||||
struct RasterizationState
|
||||
{
|
||||
uint32 depthClampEnable = 0;
|
||||
uint32 rasterizerDiscardEnable = 0;
|
||||
SePolygonMode polygonMode = Gfx::SE_POLYGON_MODE_FILL;
|
||||
SeCullModeFlags cullMode = Gfx::SE_CULL_MODE_BACK_BIT;
|
||||
SeFrontFace frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
uint32 depthBiasEnable = 0;
|
||||
float depthBiasConstantFactor = 0;
|
||||
float depthBiasClamp = 0;
|
||||
float depthBiasSlopeFactor = 0;
|
||||
float lineWidth = 1.0;
|
||||
};
|
||||
struct MultisampleState
|
||||
{
|
||||
SeSampleCountFlags samples = 1;
|
||||
uint32 sampleShadingEnable = 0;
|
||||
float minSampleShading = 1;
|
||||
uint8 alphaCoverageEnable = 0;
|
||||
uint8 alphaToOneEnable = 0;
|
||||
};
|
||||
struct DepthStencilState
|
||||
{
|
||||
uint32 depthTestEnable = 1;
|
||||
uint32 depthWriteEnable = 1;
|
||||
SeCompareOp depthCompareOp = Gfx::SE_COMPARE_OP_GREATER;
|
||||
uint32 depthBoundsTestEnable = 0;
|
||||
uint32 stencilTestEnable = 0;
|
||||
SeStencilOp front = Gfx::SE_STENCIL_OP_ZERO;
|
||||
SeStencilOp back = Gfx::SE_STENCIL_OP_ZERO;
|
||||
float minDepthBounds = 0.0f;
|
||||
float maxDepthBounds = 1.0f;
|
||||
};
|
||||
struct ColorBlendState
|
||||
{
|
||||
struct BlendAttachment
|
||||
{
|
||||
uint32 blendEnable = 0;
|
||||
SeBlendFactor srcColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
SeBlendFactor dstColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
SeBlendOp colorBlendOp = Gfx::SE_BLEND_OP_ADD;
|
||||
SeBlendFactor srcAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
SeBlendFactor dstAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
SeBlendOp alphaBlendOp = Gfx::SE_BLEND_OP_ADD;
|
||||
SeColorComponentFlags 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;
|
||||
};
|
||||
uint32 logicOpEnable = 0;
|
||||
SeLogicOp logicOp = Gfx::SE_LOGIC_OP_OR;
|
||||
uint32 attachmentCount = 0;
|
||||
StaticArray<BlendAttachment, 16> blendAttachments;
|
||||
StaticArray<float, 4> blendConstants = { 1.0f, 1.0f, 1.0f, 1.0f, };
|
||||
};
|
||||
namespace Seele {
|
||||
struct GraphicsInitializer {
|
||||
const char* applicationName;
|
||||
const char* engineName;
|
||||
const char* windowLayoutFile;
|
||||
/**
|
||||
* layers defines the enabled Vulkan layers used in the instance,
|
||||
* if ENABLE_VALIDATION is defined, standard validation is already enabled
|
||||
* not yet implemented
|
||||
*/
|
||||
Array<const char*> layers;
|
||||
Array<const char*> instanceExtensions;
|
||||
Array<const char*> deviceExtensions;
|
||||
|
||||
DECLARE_REF(VertexInput)
|
||||
DECLARE_REF(VertexShader)
|
||||
DECLARE_REF(TaskShader)
|
||||
DECLARE_REF(MeshShader)
|
||||
DECLARE_REF(FragmentShader)
|
||||
DECLARE_REF(ComputeShader)
|
||||
DECLARE_REF(RenderPass)
|
||||
DECLARE_REF(PipelineLayout)
|
||||
struct LegacyPipelineCreateInfo
|
||||
{
|
||||
SePrimitiveTopology topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
PVertexInput vertexInput = nullptr;
|
||||
PVertexShader vertexShader = nullptr;
|
||||
PFragmentShader fragmentShader = nullptr;
|
||||
PRenderPass renderPass = nullptr;
|
||||
PPipelineLayout pipelineLayout = nullptr;
|
||||
MultisampleState multisampleState;
|
||||
RasterizationState rasterizationState;
|
||||
DepthStencilState depthStencilState;
|
||||
ColorBlendState colorBlend;
|
||||
};
|
||||
void* windowHandle;
|
||||
GraphicsInitializer()
|
||||
: applicationName("SeeleEngine"), engineName("SeeleEngine"), windowLayoutFile(nullptr), layers{"VK_LAYER_LUNARG_monitor"},
|
||||
instanceExtensions{}, deviceExtensions{"VK_KHR_swapchain"}, windowHandle(nullptr) {}
|
||||
};
|
||||
struct WindowCreateInfo {
|
||||
int32 width;
|
||||
int32 height;
|
||||
const char* title;
|
||||
Gfx::SeFormat preferredFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM;
|
||||
void* windowHandle;
|
||||
};
|
||||
struct ViewportCreateInfo {
|
||||
URect dimensions;
|
||||
float fieldOfView = 1.222f; // 70 deg
|
||||
Gfx::SeSampleCountFlags numSamples;
|
||||
};
|
||||
// doesnt own the data, only proxy it
|
||||
struct DataSource {
|
||||
uint64 size = 0;
|
||||
uint64 offset = 0;
|
||||
uint8* data = nullptr;
|
||||
Gfx::QueueType owner = Gfx::QueueType::GRAPHICS;
|
||||
};
|
||||
struct TextureCreateInfo {
|
||||
DataSource sourceData = DataSource();
|
||||
Gfx::SeFormat format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT;
|
||||
uint32 width = 1;
|
||||
uint32 height = 1;
|
||||
uint32 depth = 1;
|
||||
uint32 mipLevels = 1;
|
||||
uint32 layers = 1;
|
||||
uint32 elements = 1;
|
||||
uint32 samples = 1;
|
||||
Gfx::SeImageUsageFlags usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT;
|
||||
Gfx::SeMemoryPropertyFlags memoryProps = Gfx::SE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
std::string name;
|
||||
};
|
||||
struct SamplerCreateInfo {
|
||||
Gfx::SeSamplerCreateFlags flags;
|
||||
Gfx::SeFilter magFilter = Gfx::SE_FILTER_LINEAR;
|
||||
Gfx::SeFilter minFilter = Gfx::SE_FILTER_LINEAR;
|
||||
Gfx::SeSamplerMipmapMode mipmapMode = Gfx::SE_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
Gfx::SeSamplerAddressMode addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
Gfx::SeSamplerAddressMode addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
Gfx::SeSamplerAddressMode addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
float mipLodBias = 0.0f;
|
||||
uint32 anisotropyEnable = 0;
|
||||
float maxAnisotropy = 0.0f;
|
||||
uint32 compareEnable = 0;
|
||||
Gfx::SeCompareOp compareOp = Gfx::SE_COMPARE_OP_NEVER;
|
||||
float minLod = 0.0f;
|
||||
float maxLod = 0.0f;
|
||||
Gfx::SeBorderColor borderColor = Gfx::SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
|
||||
uint32 unnormalizedCoordinates = 0;
|
||||
std::string name;
|
||||
};
|
||||
struct VertexBufferCreateInfo {
|
||||
DataSource sourceData = DataSource();
|
||||
// bytes per vertex
|
||||
uint32 vertexSize = 0;
|
||||
uint32 numVertices = 0;
|
||||
std::string name = "Unnamed";
|
||||
};
|
||||
struct IndexBufferCreateInfo {
|
||||
DataSource sourceData = DataSource();
|
||||
Gfx::SeIndexType indexType = Gfx::SeIndexType::SE_INDEX_TYPE_UINT16;
|
||||
std::string name = "Unnamed";
|
||||
};
|
||||
struct UniformBufferCreateInfo {
|
||||
DataSource sourceData = DataSource();
|
||||
uint8 dynamic = 0;
|
||||
std::string name = "Unnamed";
|
||||
};
|
||||
struct ShaderBufferCreateInfo {
|
||||
DataSource sourceData = DataSource();
|
||||
uint64 numElements = 1;
|
||||
uint8 dynamic = 0;
|
||||
uint8 vertexBuffer = 0;
|
||||
std::string name = "Unnamed";
|
||||
};
|
||||
DECLARE_NAME_REF(Gfx, PipelineLayout)
|
||||
struct ShaderCreateInfo {
|
||||
std::string name; // Debug info
|
||||
std::string mainModule;
|
||||
Array<std::string> additionalModules;
|
||||
std::string entryPoint;
|
||||
Array<Pair<const char*, const char*>> typeParameter;
|
||||
Map<const char*, const char*> defines;
|
||||
Gfx::PPipelineLayout rootSignature;
|
||||
};
|
||||
struct VertexInputBinding {
|
||||
uint32 binding;
|
||||
uint32 stride;
|
||||
Gfx::SeVertexInputRate inputRate;
|
||||
};
|
||||
struct VertexInputAttribute {
|
||||
uint32 location;
|
||||
uint32 binding;
|
||||
Gfx::SeFormat format;
|
||||
uint32 offset;
|
||||
};
|
||||
struct VertexInputStateCreateInfo {
|
||||
Array<VertexInputBinding> bindings;
|
||||
Array<VertexInputAttribute> attributes;
|
||||
};
|
||||
DECLARE_REF(MaterialInstance)
|
||||
DECLARE_REF(Mesh)
|
||||
namespace Gfx {
|
||||
struct SePushConstantRange {
|
||||
SeShaderStageFlags stageFlags;
|
||||
uint32 offset;
|
||||
uint32 size;
|
||||
};
|
||||
struct RasterizationState {
|
||||
uint32 depthClampEnable = 0;
|
||||
uint32 rasterizerDiscardEnable = 0;
|
||||
SePolygonMode polygonMode = Gfx::SE_POLYGON_MODE_FILL;
|
||||
SeCullModeFlags cullMode = Gfx::SE_CULL_MODE_BACK_BIT;
|
||||
SeFrontFace frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
uint32 depthBiasEnable = 0;
|
||||
float depthBiasConstantFactor = 0;
|
||||
float depthBiasClamp = 0;
|
||||
float depthBiasSlopeFactor = 0;
|
||||
float lineWidth = 1.0;
|
||||
};
|
||||
struct MultisampleState {
|
||||
SeSampleCountFlags samples = 1;
|
||||
uint32 sampleShadingEnable = 0;
|
||||
float minSampleShading = 1;
|
||||
uint8 alphaCoverageEnable = 0;
|
||||
uint8 alphaToOneEnable = 0;
|
||||
};
|
||||
struct DepthStencilState {
|
||||
uint32 depthTestEnable = 1;
|
||||
uint32 depthWriteEnable = 1;
|
||||
SeCompareOp depthCompareOp = Gfx::SE_COMPARE_OP_GREATER;
|
||||
uint32 depthBoundsTestEnable = 0;
|
||||
uint32 stencilTestEnable = 0;
|
||||
SeStencilOp front = Gfx::SE_STENCIL_OP_ZERO;
|
||||
SeStencilOp back = Gfx::SE_STENCIL_OP_ZERO;
|
||||
float minDepthBounds = 0.0f;
|
||||
float maxDepthBounds = 1.0f;
|
||||
};
|
||||
struct ColorBlendState {
|
||||
struct BlendAttachment {
|
||||
uint32 blendEnable = 0;
|
||||
SeBlendFactor srcColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
SeBlendFactor dstColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
SeBlendOp colorBlendOp = Gfx::SE_BLEND_OP_ADD;
|
||||
SeBlendFactor srcAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
SeBlendFactor dstAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
SeBlendOp alphaBlendOp = Gfx::SE_BLEND_OP_ADD;
|
||||
SeColorComponentFlags 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;
|
||||
};
|
||||
uint32 logicOpEnable = 0;
|
||||
SeLogicOp logicOp = Gfx::SE_LOGIC_OP_OR;
|
||||
uint32 attachmentCount = 0;
|
||||
StaticArray<BlendAttachment, 16> blendAttachments;
|
||||
StaticArray<float, 4> blendConstants = {
|
||||
1.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
};
|
||||
};
|
||||
|
||||
struct MeshPipelineCreateInfo
|
||||
{
|
||||
PTaskShader taskShader = nullptr;
|
||||
PMeshShader meshShader = nullptr;
|
||||
PFragmentShader fragmentShader = nullptr;
|
||||
PRenderPass renderPass = nullptr;
|
||||
PPipelineLayout pipelineLayout = nullptr;
|
||||
MultisampleState multisampleState;
|
||||
RasterizationState rasterizationState;
|
||||
DepthStencilState depthStencilState;
|
||||
ColorBlendState colorBlend;
|
||||
};
|
||||
struct ComputePipelineCreateInfo
|
||||
{
|
||||
Gfx::PComputeShader computeShader = nullptr;
|
||||
Gfx::PPipelineLayout pipelineLayout = nullptr;
|
||||
};
|
||||
DECLARE_REF(ShaderBuffer)
|
||||
struct BottomLevelASCreateInfo
|
||||
{
|
||||
PShaderBuffer positionBuffer;
|
||||
PShaderBuffer indexBuffer;
|
||||
MeshData meshData;
|
||||
PMaterialInstance material;
|
||||
uint64 verticesOffset;
|
||||
uint64 indicesOffset;
|
||||
};
|
||||
struct TopLevelASCreateInfo
|
||||
{
|
||||
DECLARE_REF(VertexInput)
|
||||
DECLARE_REF(VertexShader)
|
||||
DECLARE_REF(TaskShader)
|
||||
DECLARE_REF(MeshShader)
|
||||
DECLARE_REF(FragmentShader)
|
||||
DECLARE_REF(ComputeShader)
|
||||
DECLARE_REF(RenderPass)
|
||||
DECLARE_REF(PipelineLayout)
|
||||
struct LegacyPipelineCreateInfo {
|
||||
SePrimitiveTopology topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
PVertexInput vertexInput = nullptr;
|
||||
PVertexShader vertexShader = nullptr;
|
||||
PFragmentShader fragmentShader = nullptr;
|
||||
PRenderPass renderPass = nullptr;
|
||||
PPipelineLayout pipelineLayout = nullptr;
|
||||
MultisampleState multisampleState;
|
||||
RasterizationState rasterizationState;
|
||||
DepthStencilState depthStencilState;
|
||||
ColorBlendState colorBlend;
|
||||
};
|
||||
|
||||
};
|
||||
} // namespace Gfx
|
||||
struct MeshPipelineCreateInfo {
|
||||
PTaskShader taskShader = nullptr;
|
||||
PMeshShader meshShader = nullptr;
|
||||
PFragmentShader fragmentShader = nullptr;
|
||||
PRenderPass renderPass = nullptr;
|
||||
PPipelineLayout pipelineLayout = nullptr;
|
||||
MultisampleState multisampleState;
|
||||
RasterizationState rasterizationState;
|
||||
DepthStencilState depthStencilState;
|
||||
ColorBlendState colorBlend;
|
||||
};
|
||||
struct ComputePipelineCreateInfo {
|
||||
Gfx::PComputeShader computeShader = nullptr;
|
||||
Gfx::PPipelineLayout pipelineLayout = nullptr;
|
||||
};
|
||||
DECLARE_REF(ShaderBuffer)
|
||||
struct BottomLevelASCreateInfo {
|
||||
PMesh mesh;
|
||||
};
|
||||
struct TopLevelASCreateInfo {};
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
#include "Mesh.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
Mesh::Mesh()
|
||||
{
|
||||
}
|
||||
Mesh::Mesh() {}
|
||||
|
||||
Mesh::~Mesh()
|
||||
{
|
||||
}
|
||||
Mesh::~Mesh() {}
|
||||
|
||||
void Mesh::save(ArchiveBuffer& buffer) const
|
||||
{
|
||||
void Mesh::save(ArchiveBuffer& buffer) const {
|
||||
Serialization::save(buffer, transform);
|
||||
Serialization::save(buffer, vertexData->getTypeName());
|
||||
Serialization::save(buffer, vertexCount);
|
||||
@@ -24,8 +20,7 @@ void Mesh::save(ArchiveBuffer& buffer) const
|
||||
vertexData->serializeMesh(id, vertexCount, buffer);
|
||||
}
|
||||
|
||||
void Mesh::load(ArchiveBuffer& buffer)
|
||||
{
|
||||
void Mesh::load(ArchiveBuffer& buffer) {
|
||||
std::string typeName;
|
||||
Serialization::load(buffer, transform);
|
||||
Serialization::load(buffer, typeName);
|
||||
|
||||
+13
-20
@@ -1,13 +1,12 @@
|
||||
#pragma once
|
||||
#include "Asset/MaterialInstanceAsset.h"
|
||||
#include "VertexData.h"
|
||||
#include "Graphics/Buffer.h"
|
||||
#include "VertexData.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class Mesh
|
||||
{
|
||||
public:
|
||||
|
||||
namespace Seele {
|
||||
class Mesh {
|
||||
public:
|
||||
Mesh();
|
||||
~Mesh();
|
||||
|
||||
@@ -21,21 +20,15 @@ public:
|
||||
Array<Meshlet> meshlets;
|
||||
void save(ArchiveBuffer& buffer) const;
|
||||
void load(ArchiveBuffer& buffer);
|
||||
private:
|
||||
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(Mesh)
|
||||
namespace Serialization
|
||||
{
|
||||
template<>
|
||||
void save(ArchiveBuffer& buffer, const OMesh& ptr)
|
||||
{
|
||||
ptr->save(buffer);
|
||||
}
|
||||
template<>
|
||||
void load(ArchiveBuffer& buffer, OMesh& ptr)
|
||||
{
|
||||
ptr = new Mesh();
|
||||
ptr->load(buffer);
|
||||
}
|
||||
namespace Serialization {
|
||||
template <> void save(ArchiveBuffer& buffer, const OMesh& ptr) { ptr->save(buffer); }
|
||||
template <> void load(ArchiveBuffer& buffer, OMesh& ptr) {
|
||||
ptr = new Mesh();
|
||||
ptr->load(buffer);
|
||||
}
|
||||
} // namespace Serialization
|
||||
} // namespace Seele
|
||||
@@ -1,18 +1,15 @@
|
||||
#pragma once
|
||||
#include "Math/AABB.h"
|
||||
namespace Seele
|
||||
{
|
||||
struct MeshData
|
||||
{
|
||||
namespace Seele {
|
||||
struct MeshData {
|
||||
AABB bounding;
|
||||
uint32 numMeshlets = 0;
|
||||
uint32 meshletOffset = 0;
|
||||
uint32 firstIndex = 0;
|
||||
uint32 numIndices = 0;
|
||||
};
|
||||
struct InstanceData
|
||||
{
|
||||
struct InstanceData {
|
||||
Matrix4 transformMatrix;
|
||||
Matrix4 inverseTransformMatrix;
|
||||
};
|
||||
}
|
||||
} // namespace Seele
|
||||
@@ -1,29 +1,26 @@
|
||||
#include "Meshlet.h"
|
||||
#include "Containers/Map.h"
|
||||
#include "Containers/List.h"
|
||||
#include "Containers/Map.h"
|
||||
#include "Containers/Set.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
struct AdjacencyInfo
|
||||
{
|
||||
struct AdjacencyInfo {
|
||||
Array<uint32> trianglesPerVertex;
|
||||
Array<uint32> indexBufferOffset;
|
||||
Array<uint32> triangleData;
|
||||
};
|
||||
|
||||
void buildAdjacency(const uint32 numVerts, const Array<uint32>& indices, AdjacencyInfo& info)
|
||||
{
|
||||
void buildAdjacency(const uint32 numVerts, const Array<uint32>& indices, AdjacencyInfo& info) {
|
||||
info.trianglesPerVertex.resize(numVerts, 0);
|
||||
for (size_t i = 0; i < indices.size(); ++i)
|
||||
{
|
||||
for (size_t i = 0; i < indices.size(); ++i) {
|
||||
info.trianglesPerVertex[indices[i]]++;
|
||||
}
|
||||
uint32 triangleOffset = 0;
|
||||
info.indexBufferOffset.resize(numVerts, 0);
|
||||
for (size_t j = 0; j < numVerts; ++j)
|
||||
{
|
||||
for (size_t j = 0; j < numVerts; ++j) {
|
||||
info.indexBufferOffset[j] = triangleOffset;
|
||||
triangleOffset += info.trianglesPerVertex[j];
|
||||
}
|
||||
@@ -31,8 +28,7 @@ void buildAdjacency(const uint32 numVerts, const Array<uint32>& indices, Adjacen
|
||||
uint32 numTriangles = indices.size() / 3;
|
||||
info.triangleData.resize(triangleOffset);
|
||||
Array<uint32> offsets = info.indexBufferOffset;
|
||||
for (uint32 k = 0; k < numTriangles; ++k)
|
||||
{
|
||||
for (uint32 k = 0; k < numTriangles; ++k) {
|
||||
int a = indices[k * 3];
|
||||
int b = indices[k * 3 + 1];
|
||||
int c = indices[k * 3 + 2];
|
||||
@@ -43,21 +39,16 @@ void buildAdjacency(const uint32 numVerts, const Array<uint32>& indices, Adjacen
|
||||
}
|
||||
}
|
||||
|
||||
int32 skipDeadEnd(const Array<uint32>& liveTriCount, List<uint32>& deadEndStack, uint32& cursor)
|
||||
{
|
||||
while (!deadEndStack.empty())
|
||||
{
|
||||
int32 skipDeadEnd(const Array<uint32>& liveTriCount, List<uint32>& deadEndStack, uint32& cursor) {
|
||||
while (!deadEndStack.empty()) {
|
||||
uint32 vertIdx = deadEndStack.front();
|
||||
deadEndStack.popFront();
|
||||
if (liveTriCount[vertIdx] > 0)
|
||||
{
|
||||
if (liveTriCount[vertIdx] > 0) {
|
||||
return vertIdx;
|
||||
}
|
||||
}
|
||||
while (cursor < liveTriCount.size())
|
||||
{
|
||||
if (liveTriCount[cursor] > 0)
|
||||
{
|
||||
while (cursor < liveTriCount.size()) {
|
||||
if (liveTriCount[cursor] > 0) {
|
||||
return cursor;
|
||||
}
|
||||
++cursor;
|
||||
@@ -65,35 +56,29 @@ int32 skipDeadEnd(const Array<uint32>& liveTriCount, List<uint32>& deadEndStack,
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32 getNextVertex(const uint32 cacheSize, const Array<uint32>& oneRing, const Array<uint32>& cacheTimeStamps, const uint32 timeStamp, const Array<uint32>& liveTriCount, List<uint32>& deadEndStack, uint32& cursor)
|
||||
{
|
||||
int32 getNextVertex(const uint32 cacheSize, const Array<uint32>& oneRing, const Array<uint32>& cacheTimeStamps, const uint32 timeStamp,
|
||||
const Array<uint32>& liveTriCount, List<uint32>& deadEndStack, uint32& cursor) {
|
||||
uint32 bestCandidate = std::numeric_limits<uint32>::max();
|
||||
int highestPriority = -1;
|
||||
for (const uint32& vertIdx : oneRing)
|
||||
{
|
||||
if (liveTriCount[vertIdx] > 0)
|
||||
{
|
||||
for (const uint32& vertIdx : oneRing) {
|
||||
if (liveTriCount[vertIdx] > 0) {
|
||||
int priority = 0;
|
||||
if (timeStamp - cacheTimeStamps[vertIdx] + 2 * liveTriCount[vertIdx] <= cacheSize)
|
||||
{
|
||||
if (timeStamp - cacheTimeStamps[vertIdx] + 2 * liveTriCount[vertIdx] <= cacheSize) {
|
||||
priority = timeStamp - cacheTimeStamps[vertIdx];
|
||||
}
|
||||
if (priority > highestPriority)
|
||||
{
|
||||
if (priority > highestPriority) {
|
||||
highestPriority = priority;
|
||||
bestCandidate = vertIdx;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(bestCandidate == std::numeric_limits<uint32>::max())
|
||||
{
|
||||
if (bestCandidate == std::numeric_limits<uint32>::max()) {
|
||||
bestCandidate = skipDeadEnd(liveTriCount, deadEndStack, cursor);
|
||||
}
|
||||
return bestCandidate;
|
||||
}
|
||||
|
||||
void tipsifyIndexBuffer(const Array<uint32>& indices, const uint32 numVerts, const uint32 cacheSize, Array<uint32>& outIndices)
|
||||
{
|
||||
void tipsifyIndexBuffer(const Array<uint32>& indices, const uint32 numVerts, const uint32 cacheSize, Array<uint32>& outIndices) {
|
||||
AdjacencyInfo adjacencyStruct;
|
||||
buildAdjacency(numVerts, indices, adjacencyStruct);
|
||||
|
||||
@@ -108,14 +93,12 @@ void tipsifyIndexBuffer(const Array<uint32>& indices, const uint32 numVerts, con
|
||||
int32 curVert = 0;
|
||||
uint32 timeStamp = cacheSize + 1;
|
||||
uint32 cursor = 1;
|
||||
while (curVert != -1)
|
||||
{
|
||||
while (curVert != -1) {
|
||||
Array<uint32> oneRing;
|
||||
const uint32* startTriPointer = &adjacencyStruct.triangleData[0] + adjacencyStruct.indexBufferOffset[curVert];
|
||||
const uint32* endTriPointer = startTriPointer + adjacencyStruct.trianglesPerVertex[curVert];
|
||||
|
||||
for (const uint32* it = startTriPointer; it != endTriPointer; ++it)
|
||||
{
|
||||
for (const uint32* it = startTriPointer; it != endTriPointer; ++it) {
|
||||
uint32 triangle = *it;
|
||||
|
||||
if (emittedTriangles[triangle])
|
||||
@@ -156,22 +139,17 @@ void tipsifyIndexBuffer(const Array<uint32>& indices, const uint32 numVerts, con
|
||||
}
|
||||
}
|
||||
|
||||
struct Triangle
|
||||
{
|
||||
struct Triangle {
|
||||
StaticArray<uint32, 3> indices;
|
||||
};
|
||||
|
||||
int findIndex(Meshlet ¤t, uint32 index)
|
||||
{
|
||||
for (uint32 i = 0; i < current.numVertices; ++i)
|
||||
{
|
||||
if (current.uniqueVertices[i] == index)
|
||||
{
|
||||
int findIndex(Meshlet& current, uint32 index) {
|
||||
for (uint32 i = 0; i < current.numVertices; ++i) {
|
||||
if (current.uniqueVertices[i] == index) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
if (current.numVertices == Gfx::numVerticesPerMeshlet)
|
||||
{
|
||||
if (current.numVertices == Gfx::numVerticesPerMeshlet) {
|
||||
return -1;
|
||||
}
|
||||
current.uniqueVertices[current.numVertices] = index;
|
||||
@@ -179,8 +157,7 @@ int findIndex(Meshlet ¤t, uint32 index)
|
||||
return current.numVertices++;
|
||||
}
|
||||
|
||||
void completeMeshlet(Array<Meshlet> &meshlets, Meshlet ¤t)
|
||||
{
|
||||
void completeMeshlet(Array<Meshlet>& meshlets, Meshlet& current) {
|
||||
meshlets.add(current);
|
||||
current = {
|
||||
.boundingBox = AABB(),
|
||||
@@ -189,14 +166,12 @@ void completeMeshlet(Array<Meshlet> &meshlets, Meshlet ¤t)
|
||||
};
|
||||
}
|
||||
|
||||
bool addTriangle(const Array<Vector>& positions, Meshlet ¤t, Triangle& tri)
|
||||
{
|
||||
bool addTriangle(const Array<Vector>& positions, Meshlet& current, Triangle& tri) {
|
||||
int f1 = findIndex(current, tri.indices[0]);
|
||||
int f2 = findIndex(current, tri.indices[1]);
|
||||
int f3 = findIndex(current, tri.indices[2]);
|
||||
|
||||
if (f1 == -1 || f2 == -1 || f3 == -1 || current.numPrimitives == Gfx::numPrimitivesPerMeshlet)
|
||||
{
|
||||
if (f1 == -1 || f2 == -1 || f3 == -1 || current.numPrimitives == Gfx::numPrimitivesPerMeshlet) {
|
||||
return false;
|
||||
}
|
||||
current.boundingBox.adjust(positions[tri.indices[0]]);
|
||||
@@ -209,36 +184,32 @@ bool addTriangle(const Array<Vector>& positions, Meshlet ¤t, Triangle& tri
|
||||
return true;
|
||||
}
|
||||
|
||||
void Meshlet::build(const Array<Vector> &positions, const Array<uint32> &indices, Array<Meshlet> &meshlets)
|
||||
{
|
||||
void Meshlet::build(const Array<Vector>& positions, const Array<uint32>& indices, Array<Meshlet>& meshlets) {
|
||||
Meshlet current = {
|
||||
.numVertices = 0,
|
||||
.numPrimitives = 0,
|
||||
};
|
||||
//Array<uint32> optimizedIndices = indices;
|
||||
//tipsifyIndexBuffer(indices, positions.size(), 25, optimizedIndices);
|
||||
// Array<uint32> optimizedIndices = indices;
|
||||
// tipsifyIndexBuffer(indices, positions.size(), 25, optimizedIndices);
|
||||
Array<Triangle> triangles(indices.size() / 3);
|
||||
for (size_t i = 0; i < triangles.size(); ++i)
|
||||
{
|
||||
for (size_t i = 0; i < triangles.size(); ++i) {
|
||||
triangles[i] = Triangle{
|
||||
.indices = {
|
||||
indices[i * 3 + 0],
|
||||
indices[i * 3 + 1],
|
||||
indices[i * 3 + 2],
|
||||
},
|
||||
.indices =
|
||||
{
|
||||
indices[i * 3 + 0],
|
||||
indices[i * 3 + 1],
|
||||
indices[i * 3 + 2],
|
||||
},
|
||||
};
|
||||
}
|
||||
while(!triangles.empty())
|
||||
{
|
||||
if (!addTriangle(positions, current, triangles.back()))
|
||||
{
|
||||
while (!triangles.empty()) {
|
||||
if (!addTriangle(positions, current, triangles.back())) {
|
||||
completeMeshlet(meshlets, current);
|
||||
addTriangle(positions, current, triangles.back());
|
||||
}
|
||||
triangles.pop();
|
||||
}
|
||||
if (current.numVertices > 0)
|
||||
{
|
||||
if (current.numVertices > 0) {
|
||||
completeMeshlet(meshlets, current);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
#pragma once
|
||||
#include "Math/AABB.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Math/AABB.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
struct Meshlet
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
struct Meshlet {
|
||||
AABB boundingBox;
|
||||
uint32 uniqueVertices[Gfx::numVerticesPerMeshlet]; // unique vertiex indices in the vertex data
|
||||
uint32 uniqueVertices[Gfx::numVerticesPerMeshlet]; // unique vertiex indices in the vertex data
|
||||
uint8 primitiveLayout[Gfx::numPrimitivesPerMeshlet * 3]; // indices into the uniqueVertices array, only uint8 needed
|
||||
uint32 numVertices;
|
||||
uint32 numPrimitives;
|
||||
|
||||
@@ -9,93 +9,93 @@
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
DECLARE_REF(Graphics)
|
||||
class BufferAllocation : public CommandBoundResource
|
||||
{
|
||||
public:
|
||||
BufferAllocation(PGraphics graphics);
|
||||
virtual ~BufferAllocation();
|
||||
MTL::Buffer* buffer = nullptr;
|
||||
uint64 size = 0;
|
||||
class BufferAllocation : public CommandBoundResource {
|
||||
public:
|
||||
BufferAllocation(PGraphics graphics);
|
||||
virtual ~BufferAllocation();
|
||||
MTL::Buffer* buffer = nullptr;
|
||||
uint64 size = 0;
|
||||
};
|
||||
DECLARE_REF(BufferAllocation)
|
||||
class Buffer {
|
||||
public:
|
||||
Buffer(PGraphics graphics, uint64 size, void *data, bool dynamic, const std::string& name);
|
||||
virtual ~Buffer();
|
||||
MTL::Buffer *getHandle() const { return buffers[currentBuffer]->buffer; }
|
||||
PBufferAllocation getAlloc() const { return buffers[currentBuffer]; }
|
||||
uint64 getSize() const { return buffers[currentBuffer]->size; }
|
||||
void *map(bool writeOnly = true);
|
||||
void *mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly);
|
||||
void unmap();
|
||||
public:
|
||||
Buffer(PGraphics graphics, uint64 size, void* data, bool dynamic, const std::string& name);
|
||||
virtual ~Buffer();
|
||||
MTL::Buffer* getHandle() const { return buffers[currentBuffer]->buffer; }
|
||||
PBufferAllocation getAlloc() const { return buffers[currentBuffer]; }
|
||||
uint64 getSize() const { return buffers[currentBuffer]->size; }
|
||||
void* map(bool writeOnly = true);
|
||||
void* mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly);
|
||||
void unmap();
|
||||
|
||||
protected:
|
||||
PGraphics graphics;
|
||||
uint32 currentBuffer = 0;
|
||||
Array<OBufferAllocation> buffers;
|
||||
bool dynamic;
|
||||
std::string name;
|
||||
void rotateBuffer(uint64 size);
|
||||
void createBuffer(uint64 size, void* data);
|
||||
protected:
|
||||
PGraphics graphics;
|
||||
uint32 currentBuffer = 0;
|
||||
Array<OBufferAllocation> buffers;
|
||||
bool dynamic;
|
||||
std::string name;
|
||||
void rotateBuffer(uint64 size);
|
||||
void createBuffer(uint64 size, void* data);
|
||||
};
|
||||
DEFINE_REF(Buffer)
|
||||
|
||||
class VertexBuffer : public Gfx::VertexBuffer, public Buffer {
|
||||
public:
|
||||
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &createInfo);
|
||||
virtual ~VertexBuffer();
|
||||
virtual void updateRegion(DataSource update) override;
|
||||
virtual void download(Array<uint8> &buffer) override;
|
||||
public:
|
||||
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo& createInfo);
|
||||
virtual ~VertexBuffer();
|
||||
virtual void updateRegion(DataSource update) override;
|
||||
virtual void download(Array<uint8>& buffer) override;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(VertexBuffer)
|
||||
class IndexBuffer : public Gfx::IndexBuffer, public Buffer {
|
||||
public:
|
||||
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &createInfo);
|
||||
virtual ~IndexBuffer();
|
||||
public:
|
||||
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo& createInfo);
|
||||
virtual ~IndexBuffer();
|
||||
|
||||
virtual void download(Array<uint8> &buffer) override;
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void download(Array<uint8>& buffer) override;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(IndexBuffer)
|
||||
DEFINE_REF(IndexBuffer)
|
||||
class UniformBuffer : public Gfx::UniformBuffer, public Buffer {
|
||||
public:
|
||||
UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &createInfo);
|
||||
virtual ~UniformBuffer();
|
||||
public:
|
||||
UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo& createInfo);
|
||||
virtual ~UniformBuffer();
|
||||
|
||||
virtual bool updateContents(const DataSource &sourceData) override;
|
||||
virtual bool updateContents(const DataSource& sourceData) override;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(UniformBuffer)
|
||||
class ShaderBuffer : public Gfx::ShaderBuffer, public Buffer {
|
||||
public:
|
||||
ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &createInfo);
|
||||
virtual ~ShaderBuffer();
|
||||
virtual void rotateBuffer(uint64 size) override;
|
||||
virtual void updateContents(const ShaderBufferCreateInfo &sourceData) override;
|
||||
virtual void *mapRegion(uint64 offset, uint64 size, bool writeOnly) override;
|
||||
virtual void unmap() override;
|
||||
public:
|
||||
ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& createInfo);
|
||||
virtual ~ShaderBuffer();
|
||||
virtual void rotateBuffer(uint64 size) override;
|
||||
virtual void updateContents(const ShaderBufferCreateInfo& sourceData) override;
|
||||
virtual void* mapRegion(uint64 offset, uint64 size, bool writeOnly) override;
|
||||
virtual void unmap() override;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(ShaderBuffer)
|
||||
} // namespace Metal
|
||||
|
||||
@@ -11,49 +11,44 @@ using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
|
||||
BufferAllocation::BufferAllocation(PGraphics graphics)
|
||||
: CommandBoundResource(graphics)
|
||||
{}
|
||||
: CommandBoundResource(graphics) {}
|
||||
|
||||
BufferAllocation::~BufferAllocation()
|
||||
{
|
||||
if(buffer != nullptr)
|
||||
{
|
||||
BufferAllocation::~BufferAllocation() {
|
||||
if (buffer != nullptr) {
|
||||
buffer->release();
|
||||
}
|
||||
}
|
||||
|
||||
Buffer::Buffer(PGraphics graphics, uint64 size, void* data, bool dynamic, const std::string& name)
|
||||
: graphics(graphics)
|
||||
, dynamic(dynamic)
|
||||
, name(name) {
|
||||
Buffer::Buffer(PGraphics graphics, uint64 size, void *data, bool dynamic,
|
||||
const std::string &name)
|
||||
: graphics(graphics), dynamic(dynamic), name(name) {
|
||||
createBuffer(size, data);
|
||||
}
|
||||
|
||||
Buffer::~Buffer() {
|
||||
for (size_t i = 0; i < buffers.size(); ++i) {
|
||||
//TODO
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
void* Buffer::map(bool) { return getHandle()->contents(); }
|
||||
void *Buffer::map(bool) { return getHandle()->contents(); }
|
||||
|
||||
void* Buffer::mapRegion(uint64 regionOffset, uint64, bool) { return (char*)getHandle()->contents() + regionOffset; }
|
||||
void *Buffer::mapRegion(uint64 regionOffset, uint64, bool) {
|
||||
return (char *)getHandle()->contents() + regionOffset;
|
||||
}
|
||||
|
||||
void Buffer::unmap() {}
|
||||
|
||||
void Buffer::rotateBuffer(uint64 size)
|
||||
{
|
||||
void Buffer::rotateBuffer(uint64 size) {
|
||||
size = std::max(getSize(), size);
|
||||
for(size_t i = 0; i < buffers.size(); ++i)
|
||||
{
|
||||
if(buffers[i]->isCurrentlyBound())
|
||||
{
|
||||
for (size_t i = 0; i < buffers.size(); ++i) {
|
||||
if (buffers[i]->isCurrentlyBound()) {
|
||||
continue;
|
||||
}
|
||||
if(buffers[i]->size < size)
|
||||
{
|
||||
if (buffers[i]->size < size) {
|
||||
buffers[i]->buffer->release();
|
||||
buffers[i]->buffer = graphics->getDevice()->newBuffer(size, MTL::StorageModeShared);
|
||||
buffers[i]->buffer =
|
||||
graphics->getDevice()->newBuffer(size, MTL::StorageModeShared);
|
||||
buffers[i]->size = size;
|
||||
}
|
||||
currentBuffer = i;
|
||||
@@ -63,79 +58,106 @@ void Buffer::rotateBuffer(uint64 size)
|
||||
currentBuffer = buffers.size() - 1;
|
||||
}
|
||||
|
||||
void Buffer::createBuffer(uint64 size, void* data)
|
||||
{
|
||||
void Buffer::createBuffer(uint64 size, void *data) {
|
||||
buffers.add(new BufferAllocation(graphics));
|
||||
if (data != nullptr) {
|
||||
buffers.back()->buffer = graphics->getDevice()->newBuffer(data, size, MTL::StorageModeShared);
|
||||
buffers.back()->buffer =
|
||||
graphics->getDevice()->newBuffer(data, size, MTL::StorageModeShared);
|
||||
} else {
|
||||
buffers.back()->buffer = graphics->getDevice()->newBuffer(size, MTL::StorageModeShared);
|
||||
buffers.back()->buffer =
|
||||
graphics->getDevice()->newBuffer(size, MTL::StorageModeShared);
|
||||
}
|
||||
buffers.back()->buffer->setLabel(NS::String::string(name.c_str(), NS::ASCIIStringEncoding));
|
||||
buffers.back()->buffer->setLabel(
|
||||
NS::String::string(name.c_str(), NS::ASCIIStringEncoding));
|
||||
}
|
||||
|
||||
VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo& createInfo)
|
||||
: Gfx::VertexBuffer(graphics->getFamilyMapping(), createInfo.numVertices, createInfo.vertexSize,
|
||||
createInfo.sourceData.owner),
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size, createInfo.sourceData.data, false, createInfo.name) {}
|
||||
VertexBuffer::VertexBuffer(PGraphics graphics,
|
||||
const VertexBufferCreateInfo &createInfo)
|
||||
: Gfx::VertexBuffer(graphics->getFamilyMapping(), createInfo.numVertices,
|
||||
createInfo.vertexSize, createInfo.sourceData.owner),
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size,
|
||||
createInfo.sourceData.data, false, createInfo.name) {
|
||||
}
|
||||
|
||||
VertexBuffer::~VertexBuffer() {}
|
||||
|
||||
void VertexBuffer::updateRegion(DataSource update) {
|
||||
void* data = getHandle()->contents();
|
||||
std::memcpy((char*)data + update.offset, update.data, update.size);
|
||||
void *data = getHandle()->contents();
|
||||
std::memcpy((char *)data + update.offset, update.data, update.size);
|
||||
}
|
||||
|
||||
void VertexBuffer::download(Array<uint8>& buffer) {
|
||||
void* data = getHandle()->contents();
|
||||
void VertexBuffer::download(Array<uint8> &buffer) {
|
||||
void *data = getHandle()->contents();
|
||||
buffer.resize(getSize());
|
||||
std::memcpy(buffer.data(), data, getSize());
|
||||
}
|
||||
|
||||
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; }
|
||||
|
||||
void VertexBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {
|
||||
|
||||
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
currentOwner = newOwner;
|
||||
}
|
||||
|
||||
IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo& createInfo)
|
||||
: Gfx::IndexBuffer(graphics->getFamilyMapping(), createInfo.sourceData.size, createInfo.indexType,
|
||||
createInfo.sourceData.owner),
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size, createInfo.sourceData.data, false, createInfo.name) {}
|
||||
void VertexBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {}
|
||||
|
||||
IndexBuffer::IndexBuffer(PGraphics graphics,
|
||||
const IndexBufferCreateInfo &createInfo)
|
||||
: Gfx::IndexBuffer(graphics->getFamilyMapping(), createInfo.sourceData.size,
|
||||
createInfo.indexType, createInfo.sourceData.owner),
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size,
|
||||
createInfo.sourceData.data, false, createInfo.name) {
|
||||
}
|
||||
|
||||
IndexBuffer::~IndexBuffer() {}
|
||||
|
||||
void IndexBuffer::download(Array<uint8>& buffer) {
|
||||
void* data = getHandle()->contents();
|
||||
void IndexBuffer::download(Array<uint8> &buffer) {
|
||||
void *data = getHandle()->contents();
|
||||
buffer.resize(getSize());
|
||||
std::memcpy(buffer.data(), data, getSize());
|
||||
}
|
||||
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; }
|
||||
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
currentOwner = newOwner;
|
||||
}
|
||||
|
||||
void IndexBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {}
|
||||
void IndexBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {}
|
||||
|
||||
UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo& createInfo)
|
||||
UniformBuffer::UniformBuffer(PGraphics graphics,
|
||||
const UniformBufferCreateInfo &createInfo)
|
||||
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData),
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size, createInfo.sourceData.data, createInfo.dynamic, createInfo.name) {}
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size,
|
||||
createInfo.sourceData.data, createInfo.dynamic,
|
||||
createInfo.name) {}
|
||||
|
||||
UniformBuffer::~UniformBuffer() {}
|
||||
|
||||
bool UniformBuffer::updateContents(const DataSource& sourceData) {
|
||||
void* data = getHandle()->contents();
|
||||
std::memcpy((char*)data + sourceData.offset, sourceData.data, sourceData.size);
|
||||
bool UniformBuffer::updateContents(const DataSource &sourceData) {
|
||||
void *data = getHandle()->contents();
|
||||
std::memcpy((char *)data + sourceData.offset, sourceData.data,
|
||||
sourceData.size);
|
||||
return true;
|
||||
}
|
||||
|
||||
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; }
|
||||
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
currentOwner = newOwner;
|
||||
}
|
||||
|
||||
void UniformBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {}
|
||||
void UniformBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
}
|
||||
|
||||
ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& createInfo)
|
||||
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), createInfo.numElements, createInfo.sourceData),
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size, createInfo.sourceData.data, createInfo.dynamic, createInfo.name) {}
|
||||
ShaderBuffer::ShaderBuffer(PGraphics graphics,
|
||||
const ShaderBufferCreateInfo &createInfo)
|
||||
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), createInfo.numElements,
|
||||
createInfo.sourceData),
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size,
|
||||
createInfo.sourceData.data, createInfo.dynamic,
|
||||
createInfo.name) {}
|
||||
|
||||
ShaderBuffer::~ShaderBuffer() {}
|
||||
|
||||
@@ -143,29 +165,28 @@ void ShaderBuffer::rotateBuffer(uint64 size) {
|
||||
Metal::Buffer::rotateBuffer(size);
|
||||
}
|
||||
|
||||
void ShaderBuffer::updateContents(const ShaderBufferCreateInfo& createInfo) {
|
||||
void ShaderBuffer::updateContents(const ShaderBufferCreateInfo &createInfo) {
|
||||
Gfx::ShaderBuffer::updateContents(createInfo);
|
||||
if(createInfo.sourceData.data == nullptr)
|
||||
{
|
||||
if (createInfo.sourceData.data == nullptr) {
|
||||
return;
|
||||
}
|
||||
void* data = map();
|
||||
std::memcpy((char*)data + createInfo.sourceData.offset, createInfo.sourceData.data, createInfo.sourceData.size);
|
||||
void *data = map();
|
||||
std::memcpy((char *)data + createInfo.sourceData.offset,
|
||||
createInfo.sourceData.data, createInfo.sourceData.size);
|
||||
unmap();
|
||||
}
|
||||
|
||||
void* ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly)
|
||||
{
|
||||
void *ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly) {
|
||||
return Metal::Buffer::mapRegion(offset, size, writeOnly);
|
||||
}
|
||||
|
||||
void ShaderBuffer::unmap()
|
||||
{
|
||||
Metal::Buffer::unmap();
|
||||
void ShaderBuffer::unmap() { Metal::Buffer::unmap(); }
|
||||
|
||||
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
currentOwner = newOwner;
|
||||
}
|
||||
|
||||
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; }
|
||||
|
||||
|
||||
void ShaderBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {}
|
||||
void ShaderBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {}
|
||||
|
||||
@@ -19,113 +19,109 @@ DECLARE_REF(IndexBuffer)
|
||||
DECLARE_REF(GraphicsPipeline)
|
||||
DECLARE_REF(ComputePipeline)
|
||||
class Command {
|
||||
public:
|
||||
Command(PGraphics graphics, MTL::CommandBuffer* cmdBuffer);
|
||||
~Command();
|
||||
void beginRenderPass(PRenderPass renderPass);
|
||||
void endRenderPass();
|
||||
void present(MTL::Drawable* drawable);
|
||||
void end(PEvent signal);
|
||||
void waitDeviceIdle();
|
||||
void signalEvent(PEvent event);
|
||||
void waitForEvent(PEvent event);
|
||||
MTL::RenderCommandEncoder* createRenderEncoder() { return parallelEncoder->renderCommandEncoder(); }
|
||||
MTL::BlitCommandEncoder* getBlitEncoder() {
|
||||
assert(!parallelEncoder);
|
||||
if(blitEncoder == nullptr)
|
||||
{
|
||||
blitEncoder = cmdBuffer->blitCommandEncoder();
|
||||
public:
|
||||
Command(PGraphics graphics, MTL::CommandBuffer* cmdBuffer);
|
||||
~Command();
|
||||
void beginRenderPass(PRenderPass renderPass);
|
||||
void endRenderPass();
|
||||
void present(MTL::Drawable* drawable);
|
||||
void end(PEvent signal);
|
||||
void waitDeviceIdle();
|
||||
void signalEvent(PEvent event);
|
||||
void waitForEvent(PEvent event);
|
||||
MTL::RenderCommandEncoder* createRenderEncoder() { return parallelEncoder->renderCommandEncoder(); }
|
||||
MTL::BlitCommandEncoder* getBlitEncoder() {
|
||||
assert(!parallelEncoder);
|
||||
if (blitEncoder == nullptr) {
|
||||
blitEncoder = cmdBuffer->blitCommandEncoder();
|
||||
}
|
||||
return blitEncoder;
|
||||
}
|
||||
return blitEncoder;
|
||||
}
|
||||
PEvent getCompletedEvent() const { return completed; }
|
||||
constexpr MTL::CommandBuffer* getHandle() const { return cmdBuffer; }
|
||||
PEvent getCompletedEvent() const { return completed; }
|
||||
constexpr MTL::CommandBuffer* getHandle() const { return cmdBuffer; }
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
OEvent completed;
|
||||
MTL::CommandBuffer* cmdBuffer;
|
||||
MTL::ParallelRenderCommandEncoder* parallelEncoder = nullptr;
|
||||
MTL::BlitCommandEncoder* blitEncoder = nullptr;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
OEvent completed;
|
||||
MTL::CommandBuffer* cmdBuffer;
|
||||
MTL::ParallelRenderCommandEncoder* parallelEncoder = nullptr;
|
||||
MTL::BlitCommandEncoder* blitEncoder = nullptr;
|
||||
};
|
||||
DEFINE_REF(Command)
|
||||
class RenderCommand : public Gfx::RenderCommand {
|
||||
public:
|
||||
RenderCommand(MTL::RenderCommandEncoder* encode, const std::string& name);
|
||||
virtual ~RenderCommand();
|
||||
void end();
|
||||
virtual void setViewport(Gfx::PViewport viewport) override;
|
||||
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) override;
|
||||
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
|
||||
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
|
||||
const void* data) override;
|
||||
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override;
|
||||
virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset,
|
||||
uint32 firstInstance) override;
|
||||
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override;
|
||||
virtual void drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) override;
|
||||
public:
|
||||
RenderCommand(MTL::RenderCommandEncoder* encode, const std::string& name);
|
||||
virtual ~RenderCommand();
|
||||
void end();
|
||||
virtual void setViewport(Gfx::PViewport viewport) override;
|
||||
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) override;
|
||||
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
|
||||
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override;
|
||||
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override;
|
||||
virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) override;
|
||||
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override;
|
||||
virtual void drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
PGraphicsPipeline boundPipeline;
|
||||
PIndexBuffer boundIndexBuffer;
|
||||
MTL::Buffer* argumentBuffer;
|
||||
MTL::RenderCommandEncoder* encoder;
|
||||
std::string name;
|
||||
MTL::RenderCommandEncoder* encoder;
|
||||
std::string name;
|
||||
};
|
||||
DEFINE_REF(RenderCommand)
|
||||
class ComputeCommand : public Gfx::ComputeCommand {
|
||||
public:
|
||||
ComputeCommand(MTL::CommandBuffer* cmdBuffer, const std::string& name);
|
||||
virtual ~ComputeCommand();
|
||||
void end();
|
||||
virtual void bindPipeline(Gfx::PComputePipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet set, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets, Array<uint32> dynamicOffsets) override;
|
||||
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
|
||||
const void* data) override;
|
||||
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override;
|
||||
public:
|
||||
ComputeCommand(MTL::CommandBuffer* cmdBuffer, const std::string& name);
|
||||
virtual ~ComputeCommand();
|
||||
void end();
|
||||
virtual void bindPipeline(Gfx::PComputePipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet set, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets, Array<uint32> dynamicOffsets) override;
|
||||
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override;
|
||||
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override;
|
||||
|
||||
private:
|
||||
PComputePipeline boundPipeline;
|
||||
MTL::CommandBuffer* commandBuffer;
|
||||
MTL::ComputeCommandEncoder* encoder;
|
||||
private:
|
||||
PComputePipeline boundPipeline;
|
||||
MTL::CommandBuffer* commandBuffer;
|
||||
MTL::ComputeCommandEncoder* encoder;
|
||||
MTL::Buffer* argumentBuffer;
|
||||
std::string name;
|
||||
std::string name;
|
||||
};
|
||||
DEFINE_REF(ComputeCommand)
|
||||
class CommandQueue {
|
||||
public:
|
||||
CommandQueue(PGraphics graphics);
|
||||
~CommandQueue();
|
||||
constexpr MTL::CommandQueue* getHandle() { return queue; }
|
||||
PCommand getCommands() { return activeCommand; }
|
||||
ORenderCommand getRenderCommand(const std::string& name);
|
||||
OComputeCommand getComputeCommand(const std::string& name);
|
||||
void executeCommands(Array<Gfx::ORenderCommand> commands);
|
||||
void executeCommands(Array<Gfx::OComputeCommand> commands);
|
||||
void submitCommands(PEvent signal = nullptr);
|
||||
public:
|
||||
CommandQueue(PGraphics graphics);
|
||||
~CommandQueue();
|
||||
constexpr MTL::CommandQueue* getHandle() { return queue; }
|
||||
PCommand getCommands() { return activeCommand; }
|
||||
ORenderCommand getRenderCommand(const std::string& name);
|
||||
OComputeCommand getComputeCommand(const std::string& name);
|
||||
void executeCommands(Array<Gfx::ORenderCommand> commands);
|
||||
void executeCommands(Array<Gfx::OComputeCommand> commands);
|
||||
void submitCommands(PEvent signal = nullptr);
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
MTL::CommandQueue* queue;
|
||||
OCommand activeCommand;
|
||||
Array<OCommand> pendingCommands;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
MTL::CommandQueue* queue;
|
||||
OCommand activeCommand;
|
||||
Array<OCommand> pendingCommands;
|
||||
};
|
||||
class IOCommandQueue {
|
||||
public:
|
||||
IOCommandQueue(PGraphics graphics);
|
||||
~IOCommandQueue();
|
||||
constexpr MTL::IOCommandQueue* getHandle() { return queue; }
|
||||
PCommand getCommands() { return activeCommand; } // TODO
|
||||
void submitCommands(PEvent signal = nullptr);
|
||||
public:
|
||||
IOCommandQueue(PGraphics graphics);
|
||||
~IOCommandQueue();
|
||||
constexpr MTL::IOCommandQueue* getHandle() { return queue; }
|
||||
PCommand getCommands() { return activeCommand; } // TODO
|
||||
void submitCommands(PEvent signal = nullptr);
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
MTL::IOCommandQueue* queue;
|
||||
OCommand activeCommand;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
MTL::IOCommandQueue* queue;
|
||||
OCommand activeCommand;
|
||||
};
|
||||
DEFINE_REF(IOCommandQueue)
|
||||
} // namespace Metal
|
||||
|
||||
@@ -16,8 +16,9 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
|
||||
Command::Command(PGraphics graphics, MTL::CommandBuffer* cmdBuffer)
|
||||
: graphics(graphics), completed(new Event(graphics)), cmdBuffer(cmdBuffer) {}
|
||||
Command::Command(PGraphics graphics, MTL::CommandBuffer *cmdBuffer)
|
||||
: graphics(graphics), completed(new Event(graphics)), cmdBuffer(cmdBuffer) {
|
||||
}
|
||||
|
||||
Command::~Command() {}
|
||||
|
||||
@@ -27,7 +28,8 @@ void Command::beginRenderPass(PRenderPass renderPass) {
|
||||
blitEncoder = nullptr;
|
||||
}
|
||||
renderPass->updateRenderPass();
|
||||
parallelEncoder = cmdBuffer->parallelRenderCommandEncoder(renderPass->getDescriptor());
|
||||
parallelEncoder =
|
||||
cmdBuffer->parallelRenderCommandEncoder(renderPass->getDescriptor());
|
||||
}
|
||||
|
||||
void Command::endRenderPass() {
|
||||
@@ -35,7 +37,9 @@ void Command::endRenderPass() {
|
||||
parallelEncoder = nullptr;
|
||||
}
|
||||
|
||||
void Command::present(MTL::Drawable* drawable) { cmdBuffer->presentDrawable(drawable); }
|
||||
void Command::present(MTL::Drawable *drawable) {
|
||||
cmdBuffer->presentDrawable(drawable);
|
||||
}
|
||||
|
||||
void Command::end(PEvent signal) {
|
||||
assert(!parallelEncoder);
|
||||
@@ -49,11 +53,16 @@ void Command::end(PEvent signal) {
|
||||
|
||||
void Command::waitDeviceIdle() { cmdBuffer->waitUntilCompleted(); }
|
||||
|
||||
void Command::signalEvent(PEvent event) { cmdBuffer->encodeSignalEvent(event->getHandle(), 1); }
|
||||
void Command::signalEvent(PEvent event) {
|
||||
cmdBuffer->encodeSignalEvent(event->getHandle(), 1);
|
||||
}
|
||||
|
||||
void Command::waitForEvent(PEvent event) { cmdBuffer->encodeWait(event->getHandle(), 1); }
|
||||
void Command::waitForEvent(PEvent event) {
|
||||
cmdBuffer->encodeWait(event->getHandle(), 1);
|
||||
}
|
||||
|
||||
RenderCommand::RenderCommand(MTL::RenderCommandEncoder* encoder, const std::string& name)
|
||||
RenderCommand::RenderCommand(MTL::RenderCommandEncoder *encoder,
|
||||
const std::string &name)
|
||||
: encoder(encoder), name(name) {}
|
||||
|
||||
RenderCommand::~RenderCommand() {}
|
||||
@@ -79,15 +88,19 @@ void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline pipeline) {
|
||||
for (auto [_, layout] : boundPipeline->getPipelineLayout()->getLayouts()) {
|
||||
argBufferSize += 3 * sizeof(uint64) * layout->getBindings().size();
|
||||
}
|
||||
argumentBuffer = boundPipeline->graphics->getDevice()->newBuffer(argBufferSize, MTL::ResourceStorageModeShared);
|
||||
argumentBuffer = boundPipeline->graphics->getDevice()->newBuffer(
|
||||
argBufferSize, MTL::ResourceStorageModeShared);
|
||||
argumentBuffer->setLabel(
|
||||
NS::String::string(boundPipeline->getPipelineLayout()->getName().c_str(), NS::ASCIIStringEncoding));
|
||||
NS::String::string(boundPipeline->getPipelineLayout()->getName().c_str(),
|
||||
NS::ASCIIStringEncoding));
|
||||
}
|
||||
|
||||
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> offsets) {
|
||||
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet,
|
||||
Array<uint32> offsets) {
|
||||
auto metalSet = descriptorSet.cast<DescriptorSet>();
|
||||
uint32 parameterIndex = boundPipeline->getPipelineLayout()->findParameter(descriptorSet->getLayout()->getName());
|
||||
uint64* topLevelTable = (uint64*)argumentBuffer->contents();
|
||||
uint32 parameterIndex = boundPipeline->getPipelineLayout()->findParameter(
|
||||
descriptorSet->getLayout()->getName());
|
||||
uint64 *topLevelTable = (uint64 *)argumentBuffer->contents();
|
||||
topLevelTable[parameterIndex] = metalSet->getBuffer()->gpuAddress();
|
||||
auto bindings = metalSet->getLayout()->getBindings();
|
||||
encoder->useResource(metalSet->getBuffer(), MTL::ResourceUsageRead);
|
||||
@@ -117,15 +130,17 @@ void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint
|
||||
}
|
||||
}
|
||||
|
||||
void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> offsets) {
|
||||
void RenderCommand::bindDescriptor(
|
||||
const Array<Gfx::PDescriptorSet> &descriptorSets, Array<uint32> offsets) {
|
||||
for (auto set : descriptorSets) {
|
||||
bindDescriptor(set, offsets);
|
||||
}
|
||||
}
|
||||
void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) {
|
||||
void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer> &buffers) {
|
||||
uint32 i = 0;
|
||||
for (auto buffer : buffers) {
|
||||
encoder->setVertexBuffer(buffer.cast<VertexBuffer>()->getHandle(), 0, METAL_VERTEXBUFFER_OFFSET + i++);
|
||||
encoder->setVertexBuffer(buffer.cast<VertexBuffer>()->getHandle(), 0,
|
||||
METAL_VERTEXBUFFER_OFFSET + i++);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,24 +148,29 @@ void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer gfxIndexBuffer) {
|
||||
boundIndexBuffer = gfxIndexBuffer.cast<IndexBuffer>();
|
||||
}
|
||||
|
||||
void RenderCommand::pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
|
||||
const void* data) {
|
||||
void RenderCommand::pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset,
|
||||
uint32 size, const void *data) {
|
||||
if (stage & Gfx::SE_SHADER_STAGE_VERTEX_BIT) {
|
||||
encoder->setVertexBytes((char*)data + offset, size, 0);
|
||||
encoder->setVertexBytes((char *)data + offset, size, 0);
|
||||
}
|
||||
if (stage & Gfx::SE_SHADER_STAGE_FRAGMENT_BIT) {
|
||||
encoder->setFragmentBytes((char*)data + offset, size, 0);
|
||||
encoder->setFragmentBytes((char *)data + offset, size, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) {
|
||||
encoder->drawPrimitives(boundPipeline->getPrimitive(), firstVertex, vertexCount, instanceCount, firstInstance);
|
||||
void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount,
|
||||
int32 firstVertex, uint32 firstInstance) {
|
||||
encoder->drawPrimitives(boundPipeline->getPrimitive(), firstVertex,
|
||||
vertexCount, instanceCount, firstInstance);
|
||||
}
|
||||
|
||||
void RenderCommand::drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset,
|
||||
void RenderCommand::drawIndexed(uint32 indexCount, uint32 instanceCount,
|
||||
int32 firstIndex, uint32 vertexOffset,
|
||||
uint32 firstInstance) {
|
||||
encoder->drawIndexedPrimitives(boundPipeline->getPrimitive(), indexCount, cast(boundIndexBuffer->getIndexType()),
|
||||
boundIndexBuffer->getHandle(), firstIndex, instanceCount, vertexOffset, firstInstance);
|
||||
encoder->drawIndexedPrimitives(boundPipeline->getPrimitive(), indexCount,
|
||||
cast(boundIndexBuffer->getIndexType()),
|
||||
boundIndexBuffer->getHandle(), firstIndex,
|
||||
instanceCount, vertexOffset, firstInstance);
|
||||
}
|
||||
|
||||
void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) {
|
||||
@@ -159,15 +179,19 @@ void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) {
|
||||
encoder->setFragmentBuffer(argumentBuffer, 0, 2);
|
||||
encoder->setMeshBuffer(argumentBuffer, 0, 2);
|
||||
encoder->setObjectBuffer(argumentBuffer, 0, 2);
|
||||
encoder->drawMeshThreadgroups(MTL::Size(groupX, groupY, groupZ), MTL::Size(128, 1, 1), MTL::Size(32, 1, 1));
|
||||
encoder->drawMeshThreadgroups(MTL::Size(groupX, groupY, groupZ),
|
||||
MTL::Size(128, 1, 1), MTL::Size(32, 1, 1));
|
||||
}
|
||||
|
||||
void RenderCommand::drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) {
|
||||
//encoder->drawMeshThreadgroups()
|
||||
void RenderCommand::drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset,
|
||||
uint32 drawCount, uint32 stride) {
|
||||
// encoder->drawMeshThreadgroups()
|
||||
}
|
||||
|
||||
ComputeCommand::ComputeCommand(MTL::CommandBuffer* cmdBuffer, const std::string& name)
|
||||
: commandBuffer(cmdBuffer), encoder(cmdBuffer->computeCommandEncoder()), name(name) {}
|
||||
ComputeCommand::ComputeCommand(MTL::CommandBuffer *cmdBuffer,
|
||||
const std::string &name)
|
||||
: commandBuffer(cmdBuffer), encoder(cmdBuffer->computeCommandEncoder()),
|
||||
name(name) {}
|
||||
|
||||
ComputeCommand::~ComputeCommand() {}
|
||||
|
||||
@@ -180,16 +204,21 @@ void ComputeCommand::bindPipeline(Gfx::PComputePipeline pipeline) {
|
||||
boundPipeline = pipeline.cast<ComputePipeline>();
|
||||
encoder->setComputePipelineState(boundPipeline->getHandle());
|
||||
argumentBuffer = boundPipeline->graphics->getDevice()->newBuffer(
|
||||
sizeof(uint64) * (boundPipeline->getPipelineLayout()->getLayouts().size() + 1), MTL::ResourceStorageModeShared);
|
||||
sizeof(uint64) *
|
||||
(boundPipeline->getPipelineLayout()->getLayouts().size() + 1),
|
||||
MTL::ResourceStorageModeShared);
|
||||
argumentBuffer->setLabel(
|
||||
NS::String::string(pipeline->getPipelineLayout()->getName().c_str(), NS::ASCIIStringEncoding));
|
||||
NS::String::string(pipeline->getPipelineLayout()->getName().c_str(),
|
||||
NS::ASCIIStringEncoding));
|
||||
}
|
||||
|
||||
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set, Array<uint32> offsets) {
|
||||
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set,
|
||||
Array<uint32> offsets) {
|
||||
auto metalSet = set.cast<DescriptorSet>();
|
||||
metalSet->bind();
|
||||
uint32 parameterIndex = boundPipeline->getPipelineLayout()->findParameter(set->getLayout()->getName());
|
||||
uint64* topLevelTable = (uint64*)argumentBuffer->contents();
|
||||
uint32 parameterIndex = boundPipeline->getPipelineLayout()->findParameter(
|
||||
set->getLayout()->getName());
|
||||
uint64 *topLevelTable = (uint64 *)argumentBuffer->contents();
|
||||
topLevelTable[parameterIndex] = metalSet->getBuffer()->gpuAddress();
|
||||
auto bindings = metalSet->getLayout()->getBindings();
|
||||
encoder->useResource(metalSet->getBuffer(), MTL::ResourceUsageRead);
|
||||
@@ -219,42 +248,45 @@ void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set, Array<uint32> offse
|
||||
}
|
||||
}
|
||||
|
||||
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& sets, Array<uint32> offsets) {
|
||||
for (auto& set : sets) {
|
||||
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet> &sets,
|
||||
Array<uint32> offsets) {
|
||||
for (auto &set : sets) {
|
||||
bindDescriptor(set, offsets);
|
||||
}
|
||||
}
|
||||
|
||||
void ComputeCommand::pushConstants(Gfx::SeShaderStageFlags, uint32 offset, uint32 size,
|
||||
const void* data) {
|
||||
encoder->setBytes((char*)data + offset, size, 0);
|
||||
void ComputeCommand::pushConstants(Gfx::SeShaderStageFlags, uint32 offset,
|
||||
uint32 size, const void *data) {
|
||||
encoder->setBytes((char *)data + offset, size, 0);
|
||||
}
|
||||
|
||||
void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) {
|
||||
// TODO
|
||||
encoder->setBuffer(argumentBuffer, 0, 2);
|
||||
encoder->dispatchThreadgroups(MTL::Size(threadX, threadY, threadZ), MTL::Size(32, 32, 1));
|
||||
encoder->dispatchThreadgroups(MTL::Size(threadX, threadY, threadZ),
|
||||
MTL::Size(32, 32, 1));
|
||||
}
|
||||
|
||||
CommandQueue::CommandQueue(PGraphics graphics) : graphics(graphics) {
|
||||
queue = graphics->getDevice()->newCommandQueue();
|
||||
MTL::CommandBufferDescriptor* descriptor = MTL::CommandBufferDescriptor::alloc()->init();
|
||||
MTL::CommandBufferDescriptor *descriptor =
|
||||
MTL::CommandBufferDescriptor::alloc()->init();
|
||||
activeCommand = new Command(graphics, queue->commandBuffer(descriptor));
|
||||
descriptor->release();
|
||||
}
|
||||
|
||||
CommandQueue::~CommandQueue() { queue->release(); }
|
||||
|
||||
ORenderCommand CommandQueue::getRenderCommand(const std::string& name) {
|
||||
ORenderCommand CommandQueue::getRenderCommand(const std::string &name) {
|
||||
return new RenderCommand(activeCommand->createRenderEncoder(), name);
|
||||
}
|
||||
|
||||
OComputeCommand CommandQueue::getComputeCommand(const std::string& name) {
|
||||
OComputeCommand CommandQueue::getComputeCommand(const std::string &name) {
|
||||
return new ComputeCommand(queue->commandBuffer(), name);
|
||||
}
|
||||
|
||||
void CommandQueue::executeCommands(Array<Gfx::ORenderCommand> commands) {
|
||||
for (auto& command : commands) {
|
||||
for (auto &command : commands) {
|
||||
auto metalCmd = Gfx::PRenderCommand(command).cast<RenderCommand>();
|
||||
metalCmd->end();
|
||||
}
|
||||
@@ -262,33 +294,38 @@ void CommandQueue::executeCommands(Array<Gfx::ORenderCommand> commands) {
|
||||
|
||||
void CommandQueue::executeCommands(Array<Gfx::OComputeCommand> commands) {
|
||||
submitCommands();
|
||||
for (auto& command : commands) {
|
||||
for (auto &command : commands) {
|
||||
auto metalCmd = Gfx::PComputeCommand(command).cast<ComputeCommand>();
|
||||
metalCmd->end();
|
||||
}
|
||||
}
|
||||
|
||||
void CommandQueue::submitCommands(PEvent signalSemaphore) {
|
||||
activeCommand->getHandle()->addCompletedHandler(MTL::CommandBufferHandler([&](MTL::CommandBuffer* cmdBuffer) {
|
||||
for (auto it = pendingCommands.begin(); it != pendingCommands.end(); it++) {
|
||||
if ((*it)->getHandle() == cmdBuffer) {
|
||||
pendingCommands.remove(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}));
|
||||
activeCommand->getHandle()->addCompletedHandler(
|
||||
MTL::CommandBufferHandler([&](MTL::CommandBuffer *cmdBuffer) {
|
||||
for (auto it = pendingCommands.begin(); it != pendingCommands.end();
|
||||
it++) {
|
||||
if ((*it)->getHandle() == cmdBuffer) {
|
||||
pendingCommands.remove(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}));
|
||||
activeCommand->end(signalSemaphore);
|
||||
activeCommand->waitDeviceIdle();
|
||||
PEvent prevCmdEvent = activeCommand->getCompletedEvent();
|
||||
pendingCommands.add(std::move(activeCommand));
|
||||
MTL::CommandBufferDescriptor* descriptor = MTL::CommandBufferDescriptor::alloc()->init();
|
||||
descriptor->setErrorOptions(MTL::CommandBufferErrorOptionEncoderExecutionStatus);
|
||||
MTL::CommandBufferDescriptor *descriptor =
|
||||
MTL::CommandBufferDescriptor::alloc()->init();
|
||||
descriptor->setErrorOptions(
|
||||
MTL::CommandBufferErrorOptionEncoderExecutionStatus);
|
||||
activeCommand = new Command(graphics, queue->commandBuffer(descriptor));
|
||||
activeCommand->waitForEvent(prevCmdEvent);
|
||||
}
|
||||
|
||||
IOCommandQueue::IOCommandQueue(PGraphics graphics) : graphics(graphics) {
|
||||
MTL::IOCommandQueueDescriptor* desc = MTL::IOCommandQueueDescriptor::alloc()->init();
|
||||
MTL::IOCommandQueueDescriptor *desc =
|
||||
MTL::IOCommandQueueDescriptor::alloc()->init();
|
||||
desc->setType(MTL::IOCommandQueueTypeConcurrent);
|
||||
desc->setPriority(MTL::IOPriorityNormal);
|
||||
queue = graphics->getDevice()->newIOCommandQueue(desc, nullptr);
|
||||
|
||||
@@ -9,75 +9,69 @@ namespace Seele {
|
||||
namespace Metal {
|
||||
DECLARE_REF(Graphics)
|
||||
class DescriptorLayout : public Gfx::DescriptorLayout {
|
||||
public:
|
||||
DescriptorLayout(PGraphics graphics, const std::string &name);
|
||||
virtual ~DescriptorLayout();
|
||||
virtual void create() override;
|
||||
public:
|
||||
DescriptorLayout(PGraphics graphics, const std::string& name);
|
||||
virtual ~DescriptorLayout();
|
||||
virtual void create() override;
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
};
|
||||
DEFINE_REF(DescriptorLayout)
|
||||
|
||||
DECLARE_REF(DescriptorSet)
|
||||
class DescriptorPool : public Gfx::DescriptorPool {
|
||||
public:
|
||||
DescriptorPool(PGraphics graphics, PDescriptorLayout layout);
|
||||
virtual ~DescriptorPool();
|
||||
virtual Gfx::PDescriptorSet allocateDescriptorSet() override;
|
||||
virtual void reset() override;
|
||||
constexpr PDescriptorLayout getLayout() const { return layout; }
|
||||
public:
|
||||
DescriptorPool(PGraphics graphics, PDescriptorLayout layout);
|
||||
virtual ~DescriptorPool();
|
||||
virtual Gfx::PDescriptorSet allocateDescriptorSet() override;
|
||||
virtual void reset() override;
|
||||
constexpr PDescriptorLayout getLayout() const { return layout; }
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PDescriptorLayout layout;
|
||||
Array<ODescriptorSet> allocatedSets;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PDescriptorLayout layout;
|
||||
Array<ODescriptorSet> allocatedSets;
|
||||
};
|
||||
DEFINE_REF(DescriptorPool)
|
||||
|
||||
class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
|
||||
public:
|
||||
DescriptorSet(PGraphics graphics, PDescriptorPool owner);
|
||||
virtual ~DescriptorSet();
|
||||
virtual void writeChanges() override;
|
||||
virtual void updateBuffer(uint32_t binding,
|
||||
Gfx::PUniformBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateSampler(uint32_t binding, Gfx::PSampler samplerState) override;
|
||||
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture,
|
||||
Gfx::PSampler sampler = nullptr) override;
|
||||
virtual void updateTextureArray(uint32_t binding,
|
||||
Array<Gfx::PTexture> texture) override;
|
||||
public:
|
||||
DescriptorSet(PGraphics graphics, PDescriptorPool owner);
|
||||
virtual ~DescriptorSet();
|
||||
virtual void writeChanges() override;
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateSampler(uint32_t binding, Gfx::PSampler samplerState) override;
|
||||
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler sampler = nullptr) override;
|
||||
virtual void updateTextureArray(uint32_t binding, Array<Gfx::PTexture> texture) override;
|
||||
|
||||
constexpr bool isCurrentlyInUse() const { return currentlyInUse; }
|
||||
constexpr void allocate() { currentlyInUse = true; }
|
||||
constexpr void free() { currentlyInUse = false; }
|
||||
constexpr bool isCurrentlyInUse() const { return currentlyInUse; }
|
||||
constexpr void allocate() { currentlyInUse = true; }
|
||||
constexpr void free() { currentlyInUse = false; }
|
||||
|
||||
constexpr MTL::Buffer *getBuffer() const { return buffer; }
|
||||
constexpr const Array<MTL::Resource *> &getBoundResources() const {
|
||||
return boundResources;
|
||||
}
|
||||
constexpr MTL::Buffer* getBuffer() const { return buffer; }
|
||||
constexpr const Array<MTL::Resource*>& getBoundResources() const { return boundResources; }
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PDescriptorPool owner;
|
||||
MTL::Buffer *buffer = nullptr;
|
||||
uint64 *argumentBuffer = nullptr;
|
||||
Array<MTL::Resource *> boundResources;
|
||||
bool currentlyInUse;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PDescriptorPool owner;
|
||||
MTL::Buffer* buffer = nullptr;
|
||||
uint64* argumentBuffer = nullptr;
|
||||
Array<MTL::Resource*> boundResources;
|
||||
bool currentlyInUse;
|
||||
};
|
||||
DEFINE_REF(DescriptorSet)
|
||||
|
||||
class PipelineLayout : public Gfx::PipelineLayout {
|
||||
public:
|
||||
PipelineLayout(PGraphics graphics, const std::string &name,
|
||||
Gfx::PPipelineLayout baseLayout);
|
||||
virtual ~PipelineLayout();
|
||||
virtual void create() override;
|
||||
public:
|
||||
PipelineLayout(PGraphics graphics, const std::string& name, Gfx::PPipelineLayout baseLayout);
|
||||
virtual ~PipelineLayout();
|
||||
virtual void create() override;
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
};
|
||||
DEFINE_REF(PipelineLayout)
|
||||
} // namespace Metal
|
||||
|
||||
@@ -94,11 +94,8 @@ void DescriptorSet::updateBuffer(uint32_t binding,
|
||||
boundResources[binding] = metalBuffer->getHandle();
|
||||
}
|
||||
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer uniformBuffer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, uint32 index,
|
||||
Gfx::PShaderBuffer uniformBuffer) {}
|
||||
|
||||
void DescriptorSet::updateSampler(uint32_t binding,
|
||||
Gfx::PSampler samplerState) {
|
||||
|
||||
@@ -3,11 +3,9 @@
|
||||
#include "Metal/MTLStageInputOutputDescriptor.hpp"
|
||||
#include "Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Metal
|
||||
{
|
||||
constexpr uint64 METAL_VERTEXBUFFER_OFFSET = 6;// something about metal vertex fetch
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
constexpr uint64 METAL_VERTEXBUFFER_OFFSET = 6; // something about metal vertex fetch
|
||||
constexpr uint64 METAL_VERTEXATTRIBUTE_OFFSET = 11;
|
||||
|
||||
MTL::PixelFormat cast(Gfx::SeFormat format);
|
||||
@@ -32,5 +30,5 @@ MTL::PrimitiveTopologyClass cast(Gfx::SePrimitiveTopology topology);
|
||||
Gfx::SePrimitiveTopology cast(MTL::PrimitiveTopologyClass topology);
|
||||
MTL::IndexType cast(Gfx::SeIndexType indexType);
|
||||
Gfx::SeIndexType cast(MTL::IndexType indexType);
|
||||
}
|
||||
}
|
||||
} // namespace Metal
|
||||
} // namespace Seele
|
||||
@@ -767,7 +767,8 @@ Gfx::SeSamplerAddressMode Seele::Metal::cast(MTL::SamplerAddressMode mode) {
|
||||
}
|
||||
}
|
||||
|
||||
MTL::PrimitiveTopologyClass Seele::Metal::cast(Gfx::SePrimitiveTopology topology) {
|
||||
MTL::PrimitiveTopologyClass
|
||||
Seele::Metal::cast(Gfx::SePrimitiveTopology topology) {
|
||||
switch (topology) {
|
||||
case Gfx::SE_PRIMITIVE_TOPOLOGY_POINT_LIST:
|
||||
return MTL::PrimitiveTopologyClassPoint;
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
#pragma once
|
||||
#include "Metal/Metal.hpp"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Metal/Metal.hpp"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Metal
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
DECLARE_REF(CommandQueue)
|
||||
DECLARE_REF(IOCommandQueue)
|
||||
DECLARE_REF(PipelineCache)
|
||||
class Graphics : public Gfx::Graphics
|
||||
{
|
||||
public:
|
||||
class Graphics : public Gfx::Graphics {
|
||||
public:
|
||||
Graphics();
|
||||
virtual ~Graphics();
|
||||
virtual void init(GraphicsInitializer initializer) override;
|
||||
|
||||
virtual Gfx::OWindow createWindow(const WindowCreateInfo &createInfo) override;
|
||||
virtual Gfx::OViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo &createInfo) override;
|
||||
|
||||
virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, Gfx::PViewport renderArea) override;
|
||||
virtual Gfx::OWindow createWindow(const WindowCreateInfo& createInfo) override;
|
||||
virtual Gfx::OViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo& createInfo) override;
|
||||
|
||||
virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies,
|
||||
Gfx::PViewport renderArea) override;
|
||||
virtual void beginRenderPass(Gfx::PRenderPass renderPass) override;
|
||||
virtual void endRenderPass() override;
|
||||
virtual void waitDeviceIdle() override;
|
||||
@@ -27,17 +26,17 @@ public:
|
||||
virtual void executeCommands(Array<Gfx::ORenderCommand> commands) override;
|
||||
virtual void executeCommands(Array<Gfx::OComputeCommand> commands) override;
|
||||
|
||||
virtual Gfx::OTexture2D createTexture2D(const TextureCreateInfo &createInfo) override;
|
||||
virtual Gfx::OTexture3D createTexture3D(const TextureCreateInfo &createInfo) override;
|
||||
virtual Gfx::OTextureCube createTextureCube(const TextureCreateInfo &createInfo) override;
|
||||
virtual Gfx::OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) override;
|
||||
virtual Gfx::OShaderBuffer createShaderBuffer(const ShaderBufferCreateInfo &bulkData) override;
|
||||
virtual Gfx::OVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) override;
|
||||
virtual Gfx::OIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) override;
|
||||
|
||||
virtual Gfx::OTexture2D createTexture2D(const TextureCreateInfo& createInfo) override;
|
||||
virtual Gfx::OTexture3D createTexture3D(const TextureCreateInfo& createInfo) override;
|
||||
virtual Gfx::OTextureCube createTextureCube(const TextureCreateInfo& createInfo) override;
|
||||
virtual Gfx::OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo& bulkData) override;
|
||||
virtual Gfx::OShaderBuffer createShaderBuffer(const ShaderBufferCreateInfo& bulkData) override;
|
||||
virtual Gfx::OVertexBuffer createVertexBuffer(const VertexBufferCreateInfo& bulkData) override;
|
||||
virtual Gfx::OIndexBuffer createIndexBuffer(const IndexBufferCreateInfo& bulkData) override;
|
||||
|
||||
virtual Gfx::ORenderCommand createRenderCommand(const std::string& name = "") override;
|
||||
virtual Gfx::OComputeCommand createComputeCommand(const std::string& name = "") override;
|
||||
|
||||
|
||||
virtual Gfx::OVertexShader createVertexShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::OFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::OComputeShader createComputeShader(const ShaderCreateInfo& createInfo) override;
|
||||
@@ -48,22 +47,23 @@ public:
|
||||
virtual Gfx::PComputePipeline createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo) override;
|
||||
virtual Gfx::OSampler createSampler(const SamplerCreateInfo& createInfo) override;
|
||||
|
||||
virtual Gfx::ODescriptorLayout createDescriptorLayout(const std::string& name = "") override;
|
||||
virtual Gfx::OPipelineLayout createPipelineLayout(const std::string& name = "", Gfx::PPipelineLayout baseLayout = nullptr) override;
|
||||
virtual Gfx::ODescriptorLayout createDescriptorLayout(const std::string& name = "") override;
|
||||
virtual Gfx::OPipelineLayout createPipelineLayout(const std::string& name = "", Gfx::PPipelineLayout baseLayout = nullptr) override;
|
||||
|
||||
virtual Gfx::OVertexInput createVertexInput(VertexInputStateCreateInfo createInfo) override;
|
||||
|
||||
virtual void resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) override;
|
||||
|
||||
|
||||
MTL::Device* getDevice() const { return device; }
|
||||
PCommandQueue getQueue() const { return queue; }
|
||||
PIOCommandQueue getIOQueue() const { return ioQueue; }
|
||||
protected:
|
||||
|
||||
protected:
|
||||
MTL::Device* device;
|
||||
OCommandQueue queue;
|
||||
OIOCommandQueue ioQueue;
|
||||
OPipelineCache cache;
|
||||
};
|
||||
DEFINE_REF(Graphics)
|
||||
} // namespace Metal
|
||||
} // namespace Metal
|
||||
} // namespace Seele
|
||||
|
||||
@@ -1,31 +1,25 @@
|
||||
#include "Graphics.h"
|
||||
#include "Buffer.h"
|
||||
#include "Command.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/Metal/Descriptor.h"
|
||||
#include "Graphics/Metal/Pipeline.h"
|
||||
#include "Graphics/Metal/PipelineCache.h"
|
||||
#include "Graphics/Metal/Resources.h"
|
||||
#include "Shader.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Resources.h"
|
||||
#include "Command.h"
|
||||
#include "Shader.h"
|
||||
#include "Window.h"
|
||||
#include "Buffer.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
|
||||
Graphics::Graphics()
|
||||
{
|
||||
|
||||
}
|
||||
Graphics::Graphics() {}
|
||||
|
||||
Graphics::~Graphics()
|
||||
{
|
||||
|
||||
}
|
||||
Graphics::~Graphics() {}
|
||||
|
||||
void Graphics::init(GraphicsInitializer)
|
||||
{
|
||||
void Graphics::init(GraphicsInitializer) {
|
||||
glfwInit();
|
||||
device = MTL::CreateSystemDefaultDevice();
|
||||
queue = new CommandQueue(this);
|
||||
@@ -34,164 +28,149 @@ void Graphics::init(GraphicsInitializer)
|
||||
meshShadingEnabled = false;
|
||||
}
|
||||
|
||||
Gfx::OWindow Graphics::createWindow(const WindowCreateInfo &createInfo)
|
||||
{
|
||||
Gfx::OWindow Graphics::createWindow(const WindowCreateInfo &createInfo) {
|
||||
return new Window(this, createInfo);
|
||||
}
|
||||
|
||||
Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreateInfo &createInfo)
|
||||
{
|
||||
Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner,
|
||||
const ViewportCreateInfo &createInfo) {
|
||||
return new Viewport(owner, createInfo);
|
||||
}
|
||||
|
||||
Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, Gfx::PViewport renderArea)
|
||||
{
|
||||
Gfx::ORenderPass
|
||||
Graphics::createRenderPass(Gfx::RenderTargetLayout layout,
|
||||
Array<Gfx::SubPassDependency> dependencies,
|
||||
Gfx::PViewport renderArea) {
|
||||
return new RenderPass(this, layout, dependencies, renderArea);
|
||||
}
|
||||
|
||||
void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
|
||||
{
|
||||
void Graphics::beginRenderPass(Gfx::PRenderPass renderPass) {
|
||||
queue->getCommands()->beginRenderPass(renderPass.cast<RenderPass>());
|
||||
}
|
||||
|
||||
void Graphics::endRenderPass()
|
||||
{
|
||||
queue->getCommands()->endRenderPass();
|
||||
}
|
||||
void Graphics::endRenderPass() { queue->getCommands()->endRenderPass(); }
|
||||
|
||||
void Graphics::waitDeviceIdle()
|
||||
{
|
||||
queue->getCommands()->waitDeviceIdle();
|
||||
}
|
||||
void Graphics::waitDeviceIdle() { queue->getCommands()->waitDeviceIdle(); }
|
||||
|
||||
void Graphics::executeCommands(Array<Gfx::ORenderCommand> commands)
|
||||
{
|
||||
queue->executeCommands(std::move(commands));
|
||||
}
|
||||
|
||||
void Graphics::executeCommands(Array<Gfx::OComputeCommand> commands)
|
||||
{
|
||||
void Graphics::executeCommands(Array<Gfx::ORenderCommand> commands) {
|
||||
queue->executeCommands(std::move(commands));
|
||||
}
|
||||
|
||||
Gfx::OTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo)
|
||||
{
|
||||
void Graphics::executeCommands(Array<Gfx::OComputeCommand> commands) {
|
||||
queue->executeCommands(std::move(commands));
|
||||
}
|
||||
|
||||
Gfx::OTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo) {
|
||||
return new Texture2D(this, createInfo);
|
||||
}
|
||||
|
||||
Gfx::OTexture3D Graphics::createTexture3D(const TextureCreateInfo &createInfo)
|
||||
{
|
||||
|
||||
Gfx::OTexture3D Graphics::createTexture3D(const TextureCreateInfo &createInfo) {
|
||||
|
||||
return new Texture3D(this, createInfo);
|
||||
}
|
||||
|
||||
Gfx::OTextureCube Graphics::createTextureCube(const TextureCreateInfo &createInfo)
|
||||
{
|
||||
Gfx::OTextureCube
|
||||
Graphics::createTextureCube(const TextureCreateInfo &createInfo) {
|
||||
return new TextureCube(this, createInfo);
|
||||
}
|
||||
|
||||
Gfx::OUniformBuffer Graphics::createUniformBuffer(const UniformBufferCreateInfo &bulkData)
|
||||
{
|
||||
Gfx::OUniformBuffer
|
||||
Graphics::createUniformBuffer(const UniformBufferCreateInfo &bulkData) {
|
||||
return new UniformBuffer(this, bulkData);
|
||||
}
|
||||
|
||||
Gfx::OShaderBuffer Graphics::createShaderBuffer(const ShaderBufferCreateInfo &bulkData)
|
||||
{
|
||||
Gfx::OShaderBuffer
|
||||
Graphics::createShaderBuffer(const ShaderBufferCreateInfo &bulkData) {
|
||||
return new ShaderBuffer(this, bulkData);
|
||||
}
|
||||
|
||||
Gfx::OVertexBuffer Graphics::createVertexBuffer(const VertexBufferCreateInfo &bulkData)
|
||||
{
|
||||
Gfx::OVertexBuffer
|
||||
Graphics::createVertexBuffer(const VertexBufferCreateInfo &bulkData) {
|
||||
return new VertexBuffer(this, bulkData);
|
||||
}
|
||||
|
||||
Gfx::OIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkData)
|
||||
{
|
||||
Gfx::OIndexBuffer
|
||||
Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkData) {
|
||||
return new IndexBuffer(this, bulkData);
|
||||
}
|
||||
|
||||
Gfx::ORenderCommand Graphics::createRenderCommand(const std::string& name)
|
||||
{
|
||||
Gfx::ORenderCommand Graphics::createRenderCommand(const std::string &name) {
|
||||
return queue->getRenderCommand(name);
|
||||
}
|
||||
|
||||
Gfx::OComputeCommand Graphics::createComputeCommand(const std::string& name)
|
||||
{
|
||||
Gfx::OComputeCommand Graphics::createComputeCommand(const std::string &name) {
|
||||
return queue->getComputeCommand(name);
|
||||
}
|
||||
|
||||
Gfx::OVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OVertexShader
|
||||
Graphics::createVertexShader(const ShaderCreateInfo &createInfo) {
|
||||
OVertexShader result = new VertexShader(this);
|
||||
result->create(createInfo);
|
||||
return result;
|
||||
}
|
||||
|
||||
Gfx::OFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OFragmentShader
|
||||
Graphics::createFragmentShader(const ShaderCreateInfo &createInfo) {
|
||||
OFragmentShader result = new FragmentShader(this);
|
||||
result->create(createInfo);
|
||||
return result;
|
||||
}
|
||||
|
||||
Gfx::OComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OComputeShader
|
||||
Graphics::createComputeShader(const ShaderCreateInfo &createInfo) {
|
||||
OComputeShader result = new ComputeShader(this);
|
||||
result->create(createInfo);
|
||||
return result;
|
||||
}
|
||||
|
||||
Gfx::OMeshShader Graphics::createMeshShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OMeshShader
|
||||
Graphics::createMeshShader(const ShaderCreateInfo &createInfo) {
|
||||
OMeshShader result = new MeshShader(this);
|
||||
result->create(createInfo);
|
||||
return result;
|
||||
}
|
||||
|
||||
Gfx::OTaskShader Graphics::createTaskShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OTaskShader
|
||||
Graphics::createTaskShader(const ShaderCreateInfo &createInfo) {
|
||||
OTaskShader result = new TaskShader(this);
|
||||
result->create(createInfo);
|
||||
return result;
|
||||
}
|
||||
|
||||
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo)
|
||||
{
|
||||
Gfx::PGraphicsPipeline
|
||||
Graphics::createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo) {
|
||||
return cache->createPipeline(std::move(createInfo));
|
||||
}
|
||||
|
||||
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo)
|
||||
{
|
||||
Gfx::PGraphicsPipeline
|
||||
Graphics::createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo) {
|
||||
return cache->createPipeline(std::move(createInfo));
|
||||
}
|
||||
|
||||
Gfx::PComputePipeline Graphics::createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo)
|
||||
{
|
||||
Gfx::PComputePipeline
|
||||
Graphics::createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo) {
|
||||
return cache->createPipeline(std::move(createInfo));
|
||||
}
|
||||
|
||||
Gfx::OSampler Graphics::createSampler(const SamplerCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OSampler Graphics::createSampler(const SamplerCreateInfo &createInfo) {
|
||||
return new Sampler(this, createInfo);
|
||||
}
|
||||
|
||||
Gfx::ODescriptorLayout Graphics::createDescriptorLayout(const std::string& name)
|
||||
{
|
||||
Gfx::ODescriptorLayout
|
||||
Graphics::createDescriptorLayout(const std::string &name) {
|
||||
return new DescriptorLayout(this, name);
|
||||
}
|
||||
|
||||
Gfx::OPipelineLayout Graphics::createPipelineLayout(const std::string& name, Gfx::PPipelineLayout baseLayout)
|
||||
{
|
||||
Gfx::OPipelineLayout
|
||||
Graphics::createPipelineLayout(const std::string &name,
|
||||
Gfx::PPipelineLayout baseLayout) {
|
||||
return new PipelineLayout(this, name, baseLayout);
|
||||
}
|
||||
|
||||
Gfx::OVertexInput Graphics::createVertexInput(VertexInputStateCreateInfo createInfo)
|
||||
{
|
||||
Gfx::OVertexInput
|
||||
Graphics::createVertexInput(VertexInputStateCreateInfo createInfo) {
|
||||
return new VertexInput(createInfo);
|
||||
}
|
||||
|
||||
void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination)
|
||||
{
|
||||
void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -7,33 +7,35 @@
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
class VertexInput : public Gfx::VertexInput {
|
||||
public:
|
||||
VertexInput(VertexInputStateCreateInfo createInfo);
|
||||
virtual ~VertexInput();
|
||||
public:
|
||||
VertexInput(VertexInputStateCreateInfo createInfo);
|
||||
virtual ~VertexInput();
|
||||
};
|
||||
DECLARE_REF(PipelineLayout)
|
||||
DECLARE_REF(Graphics)
|
||||
class GraphicsPipeline : public Gfx::GraphicsPipeline {
|
||||
public:
|
||||
GraphicsPipeline(PGraphics graphics, MTL::PrimitiveType primitive, MTL::RenderPipelineState* pipeline, Gfx::PPipelineLayout createInfo);
|
||||
virtual ~GraphicsPipeline();
|
||||
constexpr MTL::RenderPipelineState* getHandle() const { return state; }
|
||||
constexpr MTL::PrimitiveType getPrimitive() const { return primitiveType; }
|
||||
PGraphics graphics;
|
||||
MTL::RenderPipelineState* state;
|
||||
MTL::PrimitiveType primitiveType;
|
||||
private:
|
||||
public:
|
||||
GraphicsPipeline(PGraphics graphics, MTL::PrimitiveType primitive, MTL::RenderPipelineState* pipeline, Gfx::PPipelineLayout createInfo);
|
||||
virtual ~GraphicsPipeline();
|
||||
constexpr MTL::RenderPipelineState* getHandle() const { return state; }
|
||||
constexpr MTL::PrimitiveType getPrimitive() const { return primitiveType; }
|
||||
PGraphics graphics;
|
||||
MTL::RenderPipelineState* state;
|
||||
MTL::PrimitiveType primitiveType;
|
||||
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(GraphicsPipeline)
|
||||
class ComputePipeline : public Gfx::ComputePipeline {
|
||||
public:
|
||||
ComputePipeline(PGraphics graphics, MTL::ComputePipelineState* pipeline, Gfx::PPipelineLayout);
|
||||
virtual ~ComputePipeline();
|
||||
constexpr MTL::ComputePipelineState* getHandle() const { return state; }
|
||||
public:
|
||||
ComputePipeline(PGraphics graphics, MTL::ComputePipelineState* pipeline, Gfx::PPipelineLayout);
|
||||
virtual ~ComputePipeline();
|
||||
constexpr MTL::ComputePipelineState* getHandle() const { return state; }
|
||||
|
||||
PGraphics graphics;
|
||||
private:
|
||||
MTL::ComputePipelineState* state;
|
||||
PGraphics graphics;
|
||||
|
||||
private:
|
||||
MTL::ComputePipelineState* state;
|
||||
};
|
||||
DEFINE_REF(ComputePipeline)
|
||||
} // namespace Metal
|
||||
|
||||
@@ -7,17 +7,22 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
|
||||
VertexInput::VertexInput(VertexInputStateCreateInfo createInfo) : Gfx::VertexInput(createInfo) {}
|
||||
VertexInput::VertexInput(VertexInputStateCreateInfo createInfo)
|
||||
: Gfx::VertexInput(createInfo) {}
|
||||
|
||||
VertexInput::~VertexInput() {}
|
||||
|
||||
GraphicsPipeline::GraphicsPipeline(PGraphics graphics, MTL::PrimitiveType primitive, MTL::RenderPipelineState* pipeline,
|
||||
GraphicsPipeline::GraphicsPipeline(PGraphics graphics,
|
||||
MTL::PrimitiveType primitive,
|
||||
MTL::RenderPipelineState *pipeline,
|
||||
Gfx::PPipelineLayout layout)
|
||||
: Gfx::GraphicsPipeline(layout), graphics(graphics), state(pipeline), primitiveType(primitive) {}
|
||||
: Gfx::GraphicsPipeline(layout), graphics(graphics), state(pipeline),
|
||||
primitiveType(primitive) {}
|
||||
|
||||
GraphicsPipeline::~GraphicsPipeline() {}
|
||||
|
||||
ComputePipeline::ComputePipeline(PGraphics graphics, MTL::ComputePipelineState* pipeline,
|
||||
ComputePipeline::ComputePipeline(PGraphics graphics,
|
||||
MTL::ComputePipelineState *pipeline,
|
||||
Gfx::PPipelineLayout layout)
|
||||
: Gfx::ComputePipeline(layout), graphics(graphics), state(pipeline) {}
|
||||
|
||||
|
||||
@@ -4,20 +4,20 @@
|
||||
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
class PipelineCache
|
||||
{
|
||||
public:
|
||||
PipelineCache(PGraphics graphics, const std::string& cacheFilePath);
|
||||
~PipelineCache();
|
||||
PGraphicsPipeline createPipeline(Gfx::LegacyPipelineCreateInfo createInfo);
|
||||
PGraphicsPipeline createPipeline(Gfx::MeshPipelineCreateInfo createInfo);
|
||||
PComputePipeline createPipeline(Gfx::ComputePipelineCreateInfo createInfo);
|
||||
private:
|
||||
PGraphics graphics;
|
||||
Map<uint32, OGraphicsPipeline> graphicsPipelines;
|
||||
Map<uint32, OComputePipeline> computePipelines;
|
||||
std::string cacheFile;
|
||||
class PipelineCache {
|
||||
public:
|
||||
PipelineCache(PGraphics graphics, const std::string& cacheFilePath);
|
||||
~PipelineCache();
|
||||
PGraphicsPipeline createPipeline(Gfx::LegacyPipelineCreateInfo createInfo);
|
||||
PGraphicsPipeline createPipeline(Gfx::MeshPipelineCreateInfo createInfo);
|
||||
PComputePipeline createPipeline(Gfx::ComputePipelineCreateInfo createInfo);
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
Map<uint32, OGraphicsPipeline> graphicsPipelines;
|
||||
Map<uint32, OComputePipeline> computePipelines;
|
||||
std::string cacheFile;
|
||||
};
|
||||
DEFINE_REF(PipelineCache)
|
||||
}
|
||||
}
|
||||
} // namespace Metal
|
||||
} // namespace Seele
|
||||
@@ -19,22 +19,30 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
|
||||
PipelineCache::PipelineCache(PGraphics graphics, const std::string& name) : graphics(graphics), cacheFile(name) {}
|
||||
PipelineCache::PipelineCache(PGraphics graphics, const std::string &name)
|
||||
: graphics(graphics), cacheFile(name) {}
|
||||
|
||||
PipelineCache::~PipelineCache() {}
|
||||
|
||||
PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo createInfo) {
|
||||
PPipelineLayout layout = Gfx::PPipelineLayout(createInfo.pipelineLayout).cast<PipelineLayout>();
|
||||
PGraphicsPipeline
|
||||
PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo createInfo) {
|
||||
PPipelineLayout layout =
|
||||
Gfx::PPipelineLayout(createInfo.pipelineLayout).cast<PipelineLayout>();
|
||||
|
||||
MTL::RenderPipelineDescriptor* pipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init();
|
||||
MTL::RenderPipelineDescriptor *pipelineDescriptor =
|
||||
MTL::RenderPipelineDescriptor::alloc()->init();
|
||||
|
||||
MTL::VertexDescriptor* vertexDescriptor = pipelineDescriptor->vertexDescriptor()->init();
|
||||
MTL::VertexAttributeDescriptorArray* attributes = vertexDescriptor->attributes()->init();
|
||||
MTL::VertexDescriptor *vertexDescriptor =
|
||||
pipelineDescriptor->vertexDescriptor()->init();
|
||||
MTL::VertexAttributeDescriptorArray *attributes =
|
||||
vertexDescriptor->attributes()->init();
|
||||
if (createInfo.vertexInput != nullptr) {
|
||||
const auto& vertexInfo = createInfo.vertexInput->getInfo();
|
||||
const auto &vertexInfo = createInfo.vertexInput->getInfo();
|
||||
for (size_t attr = 0; attr < vertexInfo.attributes.size(); ++attr) {
|
||||
MTL::VertexAttributeDescriptor* attribute = attributes->object(attr + METAL_VERTEXATTRIBUTE_OFFSET)->init();
|
||||
attribute->setBufferIndex(vertexInfo.attributes[attr].binding + METAL_VERTEXBUFFER_OFFSET);
|
||||
MTL::VertexAttributeDescriptor *attribute =
|
||||
attributes->object(attr + METAL_VERTEXATTRIBUTE_OFFSET)->init();
|
||||
attribute->setBufferIndex(vertexInfo.attributes[attr].binding +
|
||||
METAL_VERTEXBUFFER_OFFSET);
|
||||
switch (vertexInfo.attributes[attr].format) {
|
||||
case Gfx::SE_FORMAT_R32G32B32_SFLOAT:
|
||||
attribute->setFormat(MTL::VertexFormatFloat3);
|
||||
@@ -45,9 +53,11 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
|
||||
attribute->setOffset(vertexInfo.attributes[attr].offset);
|
||||
}
|
||||
|
||||
MTL::VertexBufferLayoutDescriptorArray* bufferLayout = vertexDescriptor->layouts()->init();
|
||||
MTL::VertexBufferLayoutDescriptorArray *bufferLayout =
|
||||
vertexDescriptor->layouts()->init();
|
||||
for (size_t binding = 0; binding < vertexInfo.bindings.size(); ++binding) {
|
||||
MTL::VertexBufferLayoutDescriptor* buffer = bufferLayout->object(binding + METAL_VERTEXBUFFER_OFFSET)->init();
|
||||
MTL::VertexBufferLayoutDescriptor *buffer =
|
||||
bufferLayout->object(binding + METAL_VERTEXBUFFER_OFFSET)->init();
|
||||
buffer->setStride(vertexInfo.bindings[binding].stride);
|
||||
buffer->setStepRate(1);
|
||||
switch (vertexInfo.bindings[binding].inputRate) {
|
||||
@@ -62,19 +72,28 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
|
||||
}
|
||||
pipelineDescriptor->setVertexDescriptor(vertexDescriptor);
|
||||
|
||||
pipelineDescriptor->setVertexFunction(createInfo.vertexShader.cast<VertexShader>()->getFunction());
|
||||
pipelineDescriptor->setVertexFunction(
|
||||
createInfo.vertexShader.cast<VertexShader>()->getFunction());
|
||||
if (createInfo.fragmentShader != nullptr) {
|
||||
pipelineDescriptor->setFragmentFunction(createInfo.fragmentShader.cast<FragmentShader>()->getFunction());
|
||||
pipelineDescriptor->setFragmentFunction(
|
||||
createInfo.fragmentShader.cast<FragmentShader>()->getFunction());
|
||||
}
|
||||
pipelineDescriptor->setInputPrimitiveTopology(cast(createInfo.topology));
|
||||
if (createInfo.renderPass->getLayout().depthAttachment.getTexture() != nullptr) {
|
||||
if (createInfo.renderPass->getLayout().depthAttachment.getTexture() !=
|
||||
nullptr) {
|
||||
pipelineDescriptor->setDepthAttachmentPixelFormat(
|
||||
cast(createInfo.renderPass->getLayout().depthAttachment.getTexture().cast<Texture2D>()->getFormat()));
|
||||
cast(createInfo.renderPass->getLayout()
|
||||
.depthAttachment.getTexture()
|
||||
.cast<Texture2D>()
|
||||
->getFormat()));
|
||||
}
|
||||
pipelineDescriptor->setAlphaToCoverageEnabled(createInfo.multisampleState.alphaCoverageEnable);
|
||||
pipelineDescriptor->setAlphaToOneEnabled(createInfo.multisampleState.alphaToOneEnable);
|
||||
pipelineDescriptor->setAlphaToCoverageEnabled(
|
||||
createInfo.multisampleState.alphaCoverageEnable);
|
||||
pipelineDescriptor->setAlphaToOneEnabled(
|
||||
createInfo.multisampleState.alphaToOneEnable);
|
||||
pipelineDescriptor->setRasterSampleCount(createInfo.multisampleState.samples);
|
||||
pipelineDescriptor->setRasterizationEnabled(!createInfo.rasterizationState.rasterizerDiscardEnable);
|
||||
pipelineDescriptor->setRasterizationEnabled(
|
||||
!createInfo.rasterizationState.rasterizerDiscardEnable);
|
||||
|
||||
uint32 hash = pipelineDescriptor->hash();
|
||||
|
||||
@@ -117,12 +136,14 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
|
||||
type = MTL::PrimitiveTypeTriangle;
|
||||
break;
|
||||
}
|
||||
NS::Error* error;
|
||||
graphicsPipelines[hash] =
|
||||
new GraphicsPipeline(graphics, type, graphics->getDevice()->newRenderPipelineState(pipelineDescriptor, &error),
|
||||
std::move(createInfo.pipelineLayout));
|
||||
NS::Error *error;
|
||||
graphicsPipelines[hash] = new GraphicsPipeline(
|
||||
graphics, type,
|
||||
graphics->getDevice()->newRenderPipelineState(pipelineDescriptor, &error),
|
||||
std::move(createInfo.pipelineLayout));
|
||||
if (error) {
|
||||
std::cout << error->localizedDescription()->cString(NS::ASCIIStringEncoding) << std::endl;
|
||||
std::cout << error->localizedDescription()->cString(NS::ASCIIStringEncoding)
|
||||
<< std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
@@ -130,51 +151,67 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
|
||||
return graphicsPipelines[hash];
|
||||
}
|
||||
|
||||
PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo createInfo) {
|
||||
MTL::MeshRenderPipelineDescriptor* pipelineDescriptor = MTL::MeshRenderPipelineDescriptor::alloc()->init();
|
||||
PGraphicsPipeline
|
||||
PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo createInfo) {
|
||||
MTL::MeshRenderPipelineDescriptor *pipelineDescriptor =
|
||||
MTL::MeshRenderPipelineDescriptor::alloc()->init();
|
||||
|
||||
pipelineDescriptor->setMeshFunction(createInfo.meshShader.cast<MeshShader>()->getFunction());
|
||||
pipelineDescriptor->setMeshFunction(
|
||||
createInfo.meshShader.cast<MeshShader>()->getFunction());
|
||||
if (createInfo.taskShader != nullptr) {
|
||||
pipelineDescriptor->setObjectFunction(createInfo.taskShader.cast<TaskShader>()->getFunction());
|
||||
pipelineDescriptor->setObjectFunction(
|
||||
createInfo.taskShader.cast<TaskShader>()->getFunction());
|
||||
}
|
||||
if (createInfo.fragmentShader != nullptr) {
|
||||
pipelineDescriptor->setFragmentFunction(createInfo.fragmentShader.cast<FragmentShader>()->getFunction());
|
||||
pipelineDescriptor->setFragmentFunction(
|
||||
createInfo.fragmentShader.cast<FragmentShader>()->getFunction());
|
||||
}
|
||||
if (createInfo.renderPass->getLayout().depthAttachment.getTexture() != nullptr) {
|
||||
if (createInfo.renderPass->getLayout().depthAttachment.getTexture() !=
|
||||
nullptr) {
|
||||
pipelineDescriptor->setDepthAttachmentPixelFormat(
|
||||
cast(createInfo.renderPass->getLayout().depthAttachment.getTexture().cast<Texture2D>()->getFormat()));
|
||||
cast(createInfo.renderPass->getLayout()
|
||||
.depthAttachment.getTexture()
|
||||
.cast<Texture2D>()
|
||||
->getFormat()));
|
||||
}
|
||||
pipelineDescriptor->setAlphaToCoverageEnabled(createInfo.multisampleState.alphaCoverageEnable);
|
||||
pipelineDescriptor->setAlphaToOneEnabled(createInfo.multisampleState.alphaToOneEnable);
|
||||
pipelineDescriptor->setAlphaToCoverageEnabled(
|
||||
createInfo.multisampleState.alphaCoverageEnable);
|
||||
pipelineDescriptor->setAlphaToOneEnabled(
|
||||
createInfo.multisampleState.alphaToOneEnable);
|
||||
pipelineDescriptor->setRasterSampleCount(createInfo.multisampleState.samples);
|
||||
pipelineDescriptor->setRasterizationEnabled(!createInfo.rasterizationState.rasterizerDiscardEnable);
|
||||
pipelineDescriptor->setRasterizationEnabled(
|
||||
!createInfo.rasterizationState.rasterizerDiscardEnable);
|
||||
|
||||
uint32 hash = pipelineDescriptor->hash();
|
||||
|
||||
if (graphicsPipelines.contains(hash)) {
|
||||
return graphicsPipelines[hash];
|
||||
}
|
||||
NS::Error* error = nullptr;
|
||||
NS::Error *error = nullptr;
|
||||
MTL::AutoreleasedRenderPipelineReflection reflection;
|
||||
graphicsPipelines[hash] = new GraphicsPipeline(
|
||||
graphics, MTL::PrimitiveTypeTriangle,
|
||||
graphics->getDevice()->newRenderPipelineState(pipelineDescriptor, MTL::PipelineOptionNone, &reflection, &error),
|
||||
graphics->getDevice()->newRenderPipelineState(
|
||||
pipelineDescriptor, MTL::PipelineOptionNone, &reflection, &error),
|
||||
std::move(createInfo.pipelineLayout));
|
||||
|
||||
pipelineDescriptor->release();
|
||||
return graphicsPipelines[hash];
|
||||
}
|
||||
|
||||
PComputePipeline PipelineCache::createPipeline(Gfx::ComputePipelineCreateInfo createInfo) {
|
||||
PComputePipeline
|
||||
PipelineCache::createPipeline(Gfx::ComputePipelineCreateInfo createInfo) {
|
||||
PComputeShader shader = createInfo.computeShader.cast<ComputeShader>();
|
||||
uint32 hash = shader->getShaderHash();
|
||||
if (computePipelines.contains(hash)) {
|
||||
return computePipelines[hash];
|
||||
}
|
||||
|
||||
NS::Error* error;
|
||||
NS::Error *error;
|
||||
computePipelines[hash] =
|
||||
new ComputePipeline(graphics, graphics->getDevice()->newComputePipelineState(shader->getFunction(), &error),
|
||||
new ComputePipeline(graphics,
|
||||
graphics->getDevice()->newComputePipelineState(
|
||||
shader->getFunction(), &error),
|
||||
std::move(createInfo.pipelineLayout));
|
||||
assert(!error);
|
||||
return computePipelines[hash];
|
||||
|
||||
@@ -2,22 +2,17 @@
|
||||
#include "Graphics/RenderTarget.h"
|
||||
#include "Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Metal
|
||||
{
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
DECLARE_REF(Graphics)
|
||||
class RenderPass : public Gfx::RenderPass
|
||||
{
|
||||
public:
|
||||
class RenderPass : public Gfx::RenderPass {
|
||||
public:
|
||||
RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, Gfx::PViewport viewport);
|
||||
virtual ~RenderPass();
|
||||
void updateRenderPass();
|
||||
MTL::RenderPassDescriptor* getDescriptor() const
|
||||
{
|
||||
return renderPass;
|
||||
}
|
||||
private:
|
||||
MTL::RenderPassDescriptor* getDescriptor() const { return renderPass; }
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
Gfx::PViewport viewport;
|
||||
MTL::RenderPassDescriptor* renderPass;
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
|
||||
RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies,
|
||||
RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout,
|
||||
Array<Gfx::SubPassDependency> dependencies,
|
||||
Gfx::PViewport viewport)
|
||||
: Gfx::RenderPass(layout, dependencies), graphics(graphics), viewport(viewport) {
|
||||
: Gfx::RenderPass(layout, dependencies), graphics(graphics),
|
||||
viewport(viewport) {
|
||||
renderPass = MTL::RenderPassDescriptor::renderPassDescriptor();
|
||||
renderPass->setRenderTargetArrayLength(1);
|
||||
renderPass->setRenderTargetWidth(viewport->getWidth());
|
||||
@@ -17,18 +19,21 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array
|
||||
renderPass->setDefaultRasterSampleCount(viewport->getSamples());
|
||||
|
||||
for (size_t i = 0; i < layout.colorAttachments.size(); ++i) {
|
||||
const auto& color = layout.colorAttachments[i];
|
||||
MTL::RenderPassColorAttachmentDescriptor* desc = renderPass->colorAttachments()->object(i);
|
||||
desc->setClearColor(MTL::ClearColor(color.clear.color.float32[0], color.clear.color.float32[1],
|
||||
color.clear.color.float32[2], color.clear.color.float32[3]));
|
||||
const auto &color = layout.colorAttachments[i];
|
||||
MTL::RenderPassColorAttachmentDescriptor *desc =
|
||||
renderPass->colorAttachments()->object(i);
|
||||
desc->setClearColor(MTL::ClearColor(
|
||||
color.clear.color.float32[0], color.clear.color.float32[1],
|
||||
color.clear.color.float32[2], color.clear.color.float32[3]));
|
||||
desc->setLoadAction(cast(color.getLoadOp()));
|
||||
desc->setStoreAction(cast(color.getStoreOp()));
|
||||
desc->setLevel(0);
|
||||
if (!layout.resolveAttachments.empty()) {
|
||||
const auto& resolve = layout.resolveAttachments[i];
|
||||
const auto &resolve = layout.resolveAttachments[i];
|
||||
desc->setResolveLevel(0);
|
||||
desc->setStoreAction(MTL::StoreActionStoreAndMultisampleResolve);
|
||||
desc->setResolveTexture(resolve.getTexture().cast<TextureBase>()->getTexture());
|
||||
desc->setResolveTexture(
|
||||
resolve.getTexture().cast<TextureBase>()->getTexture());
|
||||
}
|
||||
}
|
||||
if (layout.depthAttachment.getTexture() != nullptr) {
|
||||
@@ -38,7 +43,9 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array
|
||||
depth->setStoreAction(cast(layout.depthAttachment.getStoreOp()));
|
||||
|
||||
if (layout.depthResolveAttachment.getTexture() != nullptr) {
|
||||
depth->setResolveTexture(layout.depthResolveAttachment.getTexture().cast<TextureBase>()->getTexture());
|
||||
depth->setResolveTexture(layout.depthResolveAttachment.getTexture()
|
||||
.cast<TextureBase>()
|
||||
->getTexture());
|
||||
depth->setStoreAction(MTL::StoreActionStoreAndMultisampleResolve);
|
||||
}
|
||||
}
|
||||
@@ -48,12 +55,13 @@ RenderPass::~RenderPass() {}
|
||||
|
||||
void RenderPass::updateRenderPass() {
|
||||
for (size_t i = 0; i < layout.colorAttachments.size(); ++i) {
|
||||
const auto& color = layout.colorAttachments[i];
|
||||
const auto &color = layout.colorAttachments[i];
|
||||
auto desc = renderPass->colorAttachments()->object(i);
|
||||
desc->setTexture(color.getTexture().cast<TextureBase>()->getTexture());
|
||||
}
|
||||
if (layout.depthAttachment.getTexture() != nullptr) {
|
||||
auto depth = renderPass->depthAttachment();
|
||||
depth->setTexture(layout.depthAttachment.getTexture().cast<TextureBase>()->getTexture());
|
||||
depth->setTexture(
|
||||
layout.depthAttachment.getTexture().cast<TextureBase>()->getTexture());
|
||||
}
|
||||
}
|
||||
@@ -10,58 +10,51 @@
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
DECLARE_REF(Graphics);
|
||||
class CommandBoundResource
|
||||
{
|
||||
public:
|
||||
CommandBoundResource(PGraphics graphics)
|
||||
: graphics(graphics)
|
||||
{
|
||||
}
|
||||
virtual ~CommandBoundResource()
|
||||
{
|
||||
class CommandBoundResource {
|
||||
public:
|
||||
CommandBoundResource(PGraphics graphics) : graphics(graphics) {}
|
||||
virtual ~CommandBoundResource() {
|
||||
if (isCurrentlyBound())
|
||||
abort();
|
||||
}
|
||||
constexpr bool isCurrentlyBound() const { return bindCount > 0; }
|
||||
constexpr void bind() { bindCount++; }
|
||||
constexpr void unbind() { bindCount--; }
|
||||
protected:
|
||||
|
||||
protected:
|
||||
PGraphics graphics;
|
||||
uint64 bindCount = 0;
|
||||
};
|
||||
DEFINE_REF(CommandBoundResource)
|
||||
|
||||
class Fence {
|
||||
public:
|
||||
Fence(PGraphics graphics);
|
||||
~Fence();
|
||||
MTL::Fence *getHandle() const { return handle; }
|
||||
public:
|
||||
Fence(PGraphics graphics);
|
||||
~Fence();
|
||||
MTL::Fence* getHandle() const { return handle; }
|
||||
|
||||
private:
|
||||
MTL::Fence *handle;
|
||||
private:
|
||||
MTL::Fence* handle;
|
||||
};
|
||||
DEFINE_REF(Fence);
|
||||
class Event {
|
||||
public:
|
||||
Event(PGraphics graphics);
|
||||
~Event();
|
||||
MTL::Event *getHandle() const { return handle; }
|
||||
public:
|
||||
Event(PGraphics graphics);
|
||||
~Event();
|
||||
MTL::Event* getHandle() const { return handle; }
|
||||
|
||||
private:
|
||||
MTL::Event *handle;
|
||||
private:
|
||||
MTL::Event* handle;
|
||||
};
|
||||
DEFINE_REF(Event)
|
||||
class Sampler : public Gfx::Sampler
|
||||
{
|
||||
public:
|
||||
Sampler(PGraphics graphics, const SamplerCreateInfo& createInfo);
|
||||
virtual ~Sampler();
|
||||
MTL::SamplerState* getHandle() const
|
||||
{
|
||||
return sampler;
|
||||
}
|
||||
private:
|
||||
MTL::SamplerState* sampler;
|
||||
class Sampler : public Gfx::Sampler {
|
||||
public:
|
||||
Sampler(PGraphics graphics, const SamplerCreateInfo& createInfo);
|
||||
virtual ~Sampler();
|
||||
MTL::SamplerState* getHandle() const { return sampler; }
|
||||
|
||||
private:
|
||||
MTL::SamplerState* sampler;
|
||||
};
|
||||
DEFINE_REF(Sampler)
|
||||
} // namespace Metal
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#include "Resources.h"
|
||||
#include "Enums.h"
|
||||
#include "Graphics.h"
|
||||
#include "Metal/MTLSampler.hpp"
|
||||
#include "Enums.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
@@ -14,9 +15,8 @@ Event::Event(PGraphics graphics) : handle(graphics->getDevice()->newEvent()) {}
|
||||
|
||||
Event::~Event() { handle->release(); }
|
||||
|
||||
Sampler::Sampler(PGraphics graphics, const SamplerCreateInfo& createInfo)
|
||||
{
|
||||
MTL::SamplerDescriptor* desc = MTL::SamplerDescriptor::alloc()->init();
|
||||
Sampler::Sampler(PGraphics graphics, const SamplerCreateInfo &createInfo) {
|
||||
MTL::SamplerDescriptor *desc = MTL::SamplerDescriptor::alloc()->init();
|
||||
desc->setBorderColor(cast(createInfo.borderColor));
|
||||
desc->setCompareFunction(cast(createInfo.compareOp));
|
||||
desc->setLodAverage(createInfo.mipLodBias);
|
||||
@@ -35,7 +35,4 @@ Sampler::Sampler(PGraphics graphics, const SamplerCreateInfo& createInfo)
|
||||
desc->release();
|
||||
}
|
||||
|
||||
Sampler::~Sampler()
|
||||
{
|
||||
sampler->release();
|
||||
}
|
||||
Sampler::~Sampler() { sampler->release(); }
|
||||
@@ -7,32 +7,32 @@ namespace Seele {
|
||||
namespace Metal {
|
||||
|
||||
class Shader {
|
||||
public:
|
||||
Shader(PGraphics graphics, Gfx::SeShaderStageFlags stage);
|
||||
virtual ~Shader();
|
||||
public:
|
||||
Shader(PGraphics graphics, Gfx::SeShaderStageFlags stage);
|
||||
virtual ~Shader();
|
||||
|
||||
void create(const ShaderCreateInfo &createInfo);
|
||||
void create(const ShaderCreateInfo& createInfo);
|
||||
|
||||
constexpr MTL::Function *getFunction() const { return function; }
|
||||
constexpr const char *getEntryPointName() const {
|
||||
// SLang renames all entry points to main, so we dont need that
|
||||
return "main"; // entryPointName.c_str();
|
||||
}
|
||||
uint32 getShaderHash() const;
|
||||
constexpr MTL::Function* getFunction() const { return function; }
|
||||
constexpr const char* getEntryPointName() const {
|
||||
// SLang renames all entry points to main, so we dont need that
|
||||
return "main"; // entryPointName.c_str();
|
||||
}
|
||||
uint32 getShaderHash() const;
|
||||
|
||||
private:
|
||||
Gfx::SeShaderStageFlags stage;
|
||||
PGraphics graphics;
|
||||
MTL::Library* library;
|
||||
MTL::Function *function;
|
||||
uint32 hash;
|
||||
private:
|
||||
Gfx::SeShaderStageFlags stage;
|
||||
PGraphics graphics;
|
||||
MTL::Library* library;
|
||||
MTL::Function* function;
|
||||
uint32 hash;
|
||||
};
|
||||
DEFINE_REF(Shader)
|
||||
|
||||
template <typename Base, Gfx::SeShaderStageFlags flags> class ShaderBase : public Base, public Shader {
|
||||
public:
|
||||
ShaderBase(PGraphics graphics) : Shader(graphics, flags) {}
|
||||
virtual ~ShaderBase() {}
|
||||
public:
|
||||
ShaderBase(PGraphics graphics) : Shader(graphics, flags) {}
|
||||
virtual ~ShaderBase() {}
|
||||
};
|
||||
using VertexShader = ShaderBase<Gfx::VertexShader, Gfx::SE_SHADER_STAGE_VERTEX_BIT>;
|
||||
using FragmentShader = ShaderBase<Gfx::FragmentShader, Gfx::SE_SHADER_STAGE_FRAGMENT_BIT>;
|
||||
|
||||
@@ -29,7 +29,7 @@ void Shader::create(const ShaderCreateInfo &createInfo) {
|
||||
Map<std::string, uint32> paramMapping;
|
||||
Slang::ComPtr<slang::IBlob> kernelBlob =
|
||||
generateShader(createInfo, SLANG_METAL, paramMapping);
|
||||
std::cout << (char*)kernelBlob->getBufferPointer() << std::endl;
|
||||
std::cout << (char *)kernelBlob->getBufferPointer() << std::endl;
|
||||
hash = CRC::Calculate(kernelBlob->getBufferPointer(),
|
||||
kernelBlob->getBufferSize(), CRC::CRC_32());
|
||||
NS::Error *error;
|
||||
@@ -43,8 +43,8 @@ void Shader::create(const ShaderCreateInfo &createInfo) {
|
||||
std::cout << error->localizedDescription()->cString(NS::ASCIIStringEncoding)
|
||||
<< std::endl;
|
||||
}
|
||||
function =
|
||||
library->newFunction(NS::String::string(createInfo.entryPoint.c_str(), NS::ASCIIStringEncoding));
|
||||
function = library->newFunction(NS::String::string(
|
||||
createInfo.entryPoint.c_str(), NS::ASCIIStringEncoding));
|
||||
if (!function) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
@@ -1,62 +1,33 @@
|
||||
#pragma once
|
||||
#include "Graphics/Texture.h"
|
||||
#include "Graphics.h"
|
||||
#include "Graphics/Texture.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Metal
|
||||
{
|
||||
class TextureBase
|
||||
{
|
||||
public:
|
||||
TextureBase(PGraphics graphics, MTL::TextureType type, const TextureCreateInfo& createInfo, Gfx::QueueType& owner, MTL::Texture* existingImage = nullptr);
|
||||
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
class TextureBase {
|
||||
public:
|
||||
TextureBase(PGraphics graphics, MTL::TextureType type, const TextureCreateInfo& createInfo, Gfx::QueueType& owner,
|
||||
MTL::Texture* existingImage = nullptr);
|
||||
virtual ~TextureBase();
|
||||
uint32 getWidth() const
|
||||
{
|
||||
return width;
|
||||
}
|
||||
uint32 getHeight() const
|
||||
{
|
||||
return height;
|
||||
}
|
||||
uint32 getDepth() const
|
||||
{
|
||||
return depth;
|
||||
}
|
||||
constexpr MTL::Texture* getTexture() const
|
||||
{
|
||||
return texture;
|
||||
}
|
||||
constexpr Gfx::SeImageLayout getLayout() const
|
||||
{
|
||||
return layout;
|
||||
}
|
||||
void setLayout(Gfx::SeImageLayout val)
|
||||
{
|
||||
layout = val;
|
||||
}
|
||||
constexpr Gfx::SeFormat getFormat() const
|
||||
{
|
||||
return format;
|
||||
}
|
||||
constexpr Gfx::SeSampleCountFlags getNumSamples() const
|
||||
{
|
||||
return samples;
|
||||
}
|
||||
constexpr uint32 getMipLevels() const
|
||||
{
|
||||
return mipLevels;
|
||||
}
|
||||
uint32 getWidth() const { return width; }
|
||||
uint32 getHeight() const { return height; }
|
||||
uint32 getDepth() const { return depth; }
|
||||
constexpr MTL::Texture* getTexture() const { return texture; }
|
||||
constexpr Gfx::SeImageLayout getLayout() const { return layout; }
|
||||
void setLayout(Gfx::SeImageLayout val) { layout = val; }
|
||||
constexpr Gfx::SeFormat getFormat() const { return format; }
|
||||
constexpr Gfx::SeSampleCountFlags getNumSamples() const { return samples; }
|
||||
constexpr uint32 getMipLevels() const { return mipLevels; }
|
||||
void executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; }
|
||||
void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage);
|
||||
void changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage);
|
||||
void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage);
|
||||
void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage);
|
||||
void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer);
|
||||
|
||||
protected:
|
||||
//Updates via reference
|
||||
protected:
|
||||
// Updates via reference
|
||||
Gfx::QueueType& currentOwner;
|
||||
PGraphics graphics;
|
||||
uint32 width;
|
||||
@@ -75,128 +46,68 @@ protected:
|
||||
friend class Graphics;
|
||||
};
|
||||
DEFINE_REF(TextureBase)
|
||||
class Texture2D : public Gfx::Texture2D, public TextureBase
|
||||
{
|
||||
public:
|
||||
class Texture2D : public Gfx::Texture2D, public TextureBase {
|
||||
public:
|
||||
Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, MTL::Texture* exisitingTexture = nullptr);
|
||||
virtual ~Texture2D();
|
||||
virtual uint32 getWidth() const override
|
||||
{
|
||||
return width;
|
||||
}
|
||||
virtual uint32 getHeight() const override
|
||||
{
|
||||
return height;
|
||||
}
|
||||
virtual uint32 getDepth() const override
|
||||
{
|
||||
return depth;
|
||||
}
|
||||
virtual Gfx::SeFormat getFormat() const override
|
||||
{
|
||||
return format;
|
||||
}
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override
|
||||
{
|
||||
return samples;
|
||||
}
|
||||
virtual uint32 getMipLevels() const override
|
||||
{
|
||||
return mipLevels;
|
||||
}
|
||||
virtual void changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual uint32 getWidth() const override { return width; }
|
||||
virtual uint32 getHeight() const override { return height; }
|
||||
virtual uint32 getDepth() const override { return depth; }
|
||||
virtual Gfx::SeFormat getFormat() const override { return format; }
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return samples; }
|
||||
virtual uint32 getMipLevels() const override { return mipLevels; }
|
||||
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(Texture2D)
|
||||
class Texture3D : public Gfx::Texture3D, public TextureBase
|
||||
{
|
||||
public:
|
||||
class Texture3D : public Gfx::Texture3D, public TextureBase {
|
||||
public:
|
||||
Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo);
|
||||
virtual ~Texture3D();
|
||||
virtual uint32 getWidth() const override
|
||||
{
|
||||
return width;
|
||||
}
|
||||
virtual uint32 getHeight() const override
|
||||
{
|
||||
return height;
|
||||
}
|
||||
virtual uint32 getDepth() const override
|
||||
{
|
||||
return depth;
|
||||
}
|
||||
virtual Gfx::SeFormat getFormat() const override
|
||||
{
|
||||
return format;
|
||||
}
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override
|
||||
{
|
||||
return samples;
|
||||
}
|
||||
virtual uint32 getMipLevels() const override
|
||||
{
|
||||
return mipLevels;
|
||||
}
|
||||
virtual void changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual uint32 getWidth() const override { return width; }
|
||||
virtual uint32 getHeight() const override { return height; }
|
||||
virtual uint32 getDepth() const override { return depth; }
|
||||
virtual Gfx::SeFormat getFormat() const override { return format; }
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return samples; }
|
||||
virtual uint32 getMipLevels() const override { return mipLevels; }
|
||||
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(Texture3D)
|
||||
class TextureCube : public Gfx::TextureCube, TextureBase
|
||||
{
|
||||
public:
|
||||
class TextureCube : public Gfx::TextureCube, TextureBase {
|
||||
public:
|
||||
TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo);
|
||||
virtual ~TextureCube();
|
||||
virtual uint32 getWidth() const override
|
||||
{
|
||||
return width;
|
||||
}
|
||||
virtual uint32 getHeight() const override
|
||||
{
|
||||
return height;
|
||||
}
|
||||
virtual uint32 getDepth() const override
|
||||
{
|
||||
return depth;
|
||||
}
|
||||
virtual Gfx::SeFormat getFormat() const override
|
||||
{
|
||||
return format;
|
||||
}
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override
|
||||
{
|
||||
return samples;
|
||||
}
|
||||
virtual uint32 getMipLevels() const override
|
||||
{
|
||||
return mipLevels;
|
||||
}
|
||||
virtual void changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual uint32 getWidth() const override { return width; }
|
||||
virtual uint32 getHeight() const override { return height; }
|
||||
virtual uint32 getDepth() const override { return depth; }
|
||||
virtual Gfx::SeFormat getFormat() const override { return format; }
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return samples; }
|
||||
virtual uint32 getMipLevels() const override { return mipLevels; }
|
||||
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||
protected:
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(TextureCube)
|
||||
}
|
||||
}
|
||||
} // namespace Metal
|
||||
} // namespace Seele
|
||||
@@ -21,18 +21,16 @@ TextureBase::TextureBase(PGraphics graphics, MTL::TextureType type,
|
||||
ownsImage(existingImage == nullptr) {
|
||||
if (existingImage == nullptr) {
|
||||
MTL::TextureUsage mtlUsage = 0;
|
||||
if(usage & Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT || usage & Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
|
||||
{
|
||||
mtlUsage |= MTL::TextureUsageRenderTarget;
|
||||
if (usage & Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ||
|
||||
usage & Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
|
||||
mtlUsage |= MTL::TextureUsageRenderTarget;
|
||||
}
|
||||
if(usage & Gfx::SE_IMAGE_USAGE_SAMPLED_BIT)
|
||||
{
|
||||
mtlUsage |= MTL::TextureUsageShaderRead;
|
||||
if (usage & Gfx::SE_IMAGE_USAGE_SAMPLED_BIT) {
|
||||
mtlUsage |= MTL::TextureUsageShaderRead;
|
||||
}
|
||||
if (usage & Gfx::SE_IMAGE_USAGE_STORAGE_BIT) {
|
||||
mtlUsage |= MTL::TextureUsageShaderWrite;
|
||||
}
|
||||
if(usage & Gfx::SE_IMAGE_USAGE_STORAGE_BIT)
|
||||
{
|
||||
mtlUsage |= MTL::TextureUsageShaderWrite;
|
||||
}
|
||||
MTL::TextureDescriptor *descriptor =
|
||||
MTL::TextureDescriptor::alloc()->init();
|
||||
descriptor->setPixelFormat(cast(format));
|
||||
@@ -44,16 +42,17 @@ TextureBase::TextureBase(PGraphics graphics, MTL::TextureType type,
|
||||
descriptor->setTextureType(type);
|
||||
descriptor->setSampleCount(samples);
|
||||
descriptor->setUsage(mtlUsage);
|
||||
|
||||
|
||||
texture = graphics->getDevice()->newTexture(descriptor);
|
||||
|
||||
descriptor->release();
|
||||
}
|
||||
// if(createInfo.sourceData.data != nullptr)
|
||||
// {
|
||||
// MTL::Region region(0, 0, 0, width, height, depth);
|
||||
// texture->replaceRegion(region, 0, createInfo.sourceData.data, createInfo.sourceData.size / (depth * height));
|
||||
// }
|
||||
// if(createInfo.sourceData.data != nullptr)
|
||||
// {
|
||||
// MTL::Region region(0, 0, 0, width, height, depth);
|
||||
// texture->replaceRegion(region, 0, createInfo.sourceData.data,
|
||||
// createInfo.sourceData.size / (depth * height));
|
||||
// }
|
||||
}
|
||||
|
||||
TextureBase::~TextureBase() {
|
||||
@@ -71,8 +70,7 @@ void TextureBase::changeLayout(Gfx::SeImageLayout, Gfx::SeAccessFlags,
|
||||
Gfx::SePipelineStageFlags, Gfx::SeAccessFlags,
|
||||
Gfx::SePipelineStageFlags) {}
|
||||
|
||||
void TextureBase::download(uint32, uint32, uint32, Array<uint8>&)
|
||||
{}
|
||||
void TextureBase::download(uint32, uint32, uint32, Array<uint8> &) {}
|
||||
|
||||
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo &createInfo,
|
||||
MTL::Texture *exisitingTexture)
|
||||
@@ -86,93 +84,95 @@ Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo &createInfo,
|
||||
: MTL::TextureType2D),
|
||||
createInfo, Gfx::Texture2D::currentOwner, exisitingTexture) {}
|
||||
|
||||
Texture2D::~Texture2D()
|
||||
{
|
||||
Texture2D::~Texture2D() {}
|
||||
|
||||
void Texture2D::changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess,
|
||||
dstStage);
|
||||
}
|
||||
|
||||
void Texture2D::changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage)
|
||||
{
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
||||
void Texture2D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face,
|
||||
Array<uint8> &buffer) {
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
}
|
||||
|
||||
void Texture2D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
|
||||
{
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
TextureBase::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
{
|
||||
TextureBase::executeOwnershipBarrier(newOwner);
|
||||
void Texture2D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
void Texture2D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage)
|
||||
{
|
||||
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo &createInfo)
|
||||
: Gfx::Texture3D(graphics->getFamilyMapping(), createInfo.sourceData.owner),
|
||||
TextureBase(graphics, MTL::TextureType3D, createInfo,
|
||||
Gfx::Texture3D::currentOwner) {}
|
||||
|
||||
Texture3D::~Texture3D() {}
|
||||
|
||||
void Texture3D::changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess,
|
||||
dstStage);
|
||||
}
|
||||
|
||||
Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo)
|
||||
: Gfx::Texture3D(graphics->getFamilyMapping(), createInfo.sourceData.owner)
|
||||
, TextureBase(graphics, MTL::TextureType3D, createInfo, Gfx::Texture3D::currentOwner) {}
|
||||
|
||||
|
||||
Texture3D::~Texture3D()
|
||||
{
|
||||
void Texture3D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face,
|
||||
Array<uint8> &buffer) {
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
}
|
||||
void Texture3D::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
TextureBase::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
void Texture3D::changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage)
|
||||
{
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
||||
void Texture3D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
void Texture3D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
|
||||
{
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
}
|
||||
void Texture3D::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
{
|
||||
TextureBase::executeOwnershipBarrier(newOwner);
|
||||
TextureCube::TextureCube(PGraphics graphics,
|
||||
const TextureCreateInfo &createInfo)
|
||||
: Gfx::TextureCube(graphics->getFamilyMapping(),
|
||||
createInfo.sourceData.owner),
|
||||
TextureBase(graphics,
|
||||
createInfo.elements > 1 ? MTL::TextureTypeCubeArray
|
||||
: MTL::TextureTypeCube,
|
||||
createInfo, Gfx::TextureCube::currentOwner) {}
|
||||
|
||||
TextureCube::~TextureCube() {}
|
||||
|
||||
void TextureCube::changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess,
|
||||
dstStage);
|
||||
}
|
||||
|
||||
void Texture3D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage)
|
||||
{
|
||||
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
void TextureCube::download(uint32 mipLevel, uint32 arrayLayer, uint32 face,
|
||||
Array<uint8> &buffer) {
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
}
|
||||
void TextureCube::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
TextureBase::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
TextureCube::TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo)
|
||||
: Gfx::TextureCube(graphics->getFamilyMapping(), createInfo.sourceData.owner)
|
||||
, TextureBase(graphics, createInfo.elements > 1 ? MTL::TextureTypeCubeArray : MTL::TextureTypeCube,
|
||||
createInfo, Gfx::TextureCube::currentOwner)
|
||||
{
|
||||
}
|
||||
|
||||
TextureCube::~TextureCube()
|
||||
{
|
||||
}
|
||||
|
||||
void TextureCube::changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage)
|
||||
{
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
void TextureCube::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
|
||||
{
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
}
|
||||
void TextureCube::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
{
|
||||
TextureBase::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
void TextureCube::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage)
|
||||
{
|
||||
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
void TextureCube::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
@@ -17,60 +17,60 @@
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
class Window : public Gfx::Window {
|
||||
public:
|
||||
Window(PGraphics graphics, const WindowCreateInfo& createInfo);
|
||||
virtual ~Window();
|
||||
virtual void pollInput() override;
|
||||
virtual void beginFrame() override;
|
||||
virtual void endFrame() override;
|
||||
virtual Gfx::PTexture2D getBackBuffer() const override;
|
||||
virtual void onWindowCloseEvent() override;
|
||||
virtual void setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback) override;
|
||||
virtual void setMouseMoveCallback(std::function<void(double, double)> callback) override;
|
||||
virtual void setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback) override;
|
||||
virtual void setScrollCallback(std::function<void(double, double)> callback) override;
|
||||
virtual void setFileCallback(std::function<void(int, const char**)> callback) override;
|
||||
virtual void setCloseCallback(std::function<void()> callback) override;
|
||||
virtual void setResizeCallback(std::function<void(uint32, uint32)> callback) override;
|
||||
public:
|
||||
Window(PGraphics graphics, const WindowCreateInfo& createInfo);
|
||||
virtual ~Window();
|
||||
virtual void pollInput() override;
|
||||
virtual void beginFrame() override;
|
||||
virtual void endFrame() override;
|
||||
virtual Gfx::PTexture2D getBackBuffer() const override;
|
||||
virtual void onWindowCloseEvent() override;
|
||||
virtual void setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback) override;
|
||||
virtual void setMouseMoveCallback(std::function<void(double, double)> callback) override;
|
||||
virtual void setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback) override;
|
||||
virtual void setScrollCallback(std::function<void(double, double)> callback) override;
|
||||
virtual void setFileCallback(std::function<void(int, const char**)> callback) override;
|
||||
virtual void setCloseCallback(std::function<void()> callback) override;
|
||||
virtual void setResizeCallback(std::function<void(uint32, uint32)> callback) override;
|
||||
|
||||
void keyPress(KeyCode code, InputAction action, KeyModifier modifier);
|
||||
void mouseMove(double x, double y);
|
||||
void mouseButton(MouseButton button, InputAction action, KeyModifier modifier);
|
||||
void scroll(double x, double y);
|
||||
void fileDrop(int num, const char** files);
|
||||
void close();
|
||||
void resize(int width, int height);
|
||||
void keyPress(KeyCode code, InputAction action, KeyModifier modifier);
|
||||
void mouseMove(double x, double y);
|
||||
void mouseButton(MouseButton button, InputAction action, KeyModifier modifier);
|
||||
void scroll(double x, double y);
|
||||
void fileDrop(int num, const char** files);
|
||||
void close();
|
||||
void resize(int width, int height);
|
||||
|
||||
private:
|
||||
void createBackBuffer();
|
||||
private:
|
||||
void createBackBuffer();
|
||||
|
||||
PGraphics graphics;
|
||||
WindowCreateInfo preferences;
|
||||
GLFWwindow* windowHandle;
|
||||
NSWindow* metalWindow;
|
||||
CAMetalLayer* metalLayer;
|
||||
CA::MetalDrawable* drawable;
|
||||
OTexture2D backBuffer;
|
||||
PGraphics graphics;
|
||||
WindowCreateInfo preferences;
|
||||
GLFWwindow* windowHandle;
|
||||
NSWindow* metalWindow;
|
||||
CAMetalLayer* metalLayer;
|
||||
CA::MetalDrawable* drawable;
|
||||
OTexture2D backBuffer;
|
||||
|
||||
std::function<void(KeyCode, InputAction, KeyModifier)> keyCallback;
|
||||
std::function<void(double, double)> mouseMoveCallback;
|
||||
std::function<void(MouseButton, InputAction, KeyModifier)> mouseButtonCallback;
|
||||
std::function<void(double, double)> scrollCallback;
|
||||
std::function<void(int, const char**)> fileCallback;
|
||||
std::function<void()> closeCallback;
|
||||
std::function<void(uint32, uint32)> resizeCallback;
|
||||
std::function<void(KeyCode, InputAction, KeyModifier)> keyCallback;
|
||||
std::function<void(double, double)> mouseMoveCallback;
|
||||
std::function<void(MouseButton, InputAction, KeyModifier)> mouseButtonCallback;
|
||||
std::function<void(double, double)> scrollCallback;
|
||||
std::function<void(int, const char**)> fileCallback;
|
||||
std::function<void()> closeCallback;
|
||||
std::function<void(uint32, uint32)> resizeCallback;
|
||||
};
|
||||
DEFINE_REF(Window);
|
||||
class Viewport : public Gfx::Viewport {
|
||||
public:
|
||||
Viewport(PWindow owner, const ViewportCreateInfo& createInfo);
|
||||
virtual ~Viewport();
|
||||
constexpr MTL::Viewport getHandle() const { return viewport; }
|
||||
virtual void resize(uint32 newX, uint32 newY);
|
||||
virtual void move(uint32 newOffset, uint32 newOffsetY);
|
||||
public:
|
||||
Viewport(PWindow owner, const ViewportCreateInfo& createInfo);
|
||||
virtual ~Viewport();
|
||||
constexpr MTL::Viewport getHandle() const { return viewport; }
|
||||
virtual void resize(uint32 newX, uint32 newY);
|
||||
virtual void move(uint32 newOffset, uint32 newOffsetY);
|
||||
|
||||
private:
|
||||
MTL::Viewport viewport;
|
||||
private:
|
||||
MTL::Viewport viewport;
|
||||
};
|
||||
} // namespace Metal
|
||||
} // namespace Seele
|
||||
|
||||
@@ -20,51 +20,58 @@ double Gfx::getCurrentFrameDelta() { return currentFrameDelta; }
|
||||
uint32 currentFrameIndex = 0;
|
||||
uint32 Gfx::getCurrentFrameIndex() { return currentFrameIndex; }
|
||||
|
||||
void glfwKeyCallback(GLFWwindow* handle, int key, int, int action, int modifier) {
|
||||
void glfwKeyCallback(GLFWwindow *handle, int key, int, int action,
|
||||
int modifier) {
|
||||
if (key == -1) {
|
||||
return;
|
||||
}
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
Window *window = (Window *)glfwGetWindowUserPointer(handle);
|
||||
window->keyPress((KeyCode)key, (InputAction)action, (KeyModifier)modifier);
|
||||
}
|
||||
|
||||
void glfwMouseMoveCallback(GLFWwindow* handle, double xpos, double ypos) {
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
void glfwMouseMoveCallback(GLFWwindow *handle, double xpos, double ypos) {
|
||||
Window *window = (Window *)glfwGetWindowUserPointer(handle);
|
||||
window->mouseMove(xpos, ypos);
|
||||
}
|
||||
|
||||
void glfwMouseButtonCallback(GLFWwindow* handle, int button, int action, int modifier) {
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
window->mouseButton((MouseButton)button, (InputAction)action, (KeyModifier)modifier);
|
||||
void glfwMouseButtonCallback(GLFWwindow *handle, int button, int action,
|
||||
int modifier) {
|
||||
Window *window = (Window *)glfwGetWindowUserPointer(handle);
|
||||
window->mouseButton((MouseButton)button, (InputAction)action,
|
||||
(KeyModifier)modifier);
|
||||
}
|
||||
|
||||
void glfwScrollCallback(GLFWwindow* handle, double xoffset, double yoffset) {
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
void glfwScrollCallback(GLFWwindow *handle, double xoffset, double yoffset) {
|
||||
Window *window = (Window *)glfwGetWindowUserPointer(handle);
|
||||
window->scroll(xoffset, yoffset);
|
||||
}
|
||||
|
||||
void glfwFileCallback(GLFWwindow* handle, int count, const char** paths) {
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
void glfwFileCallback(GLFWwindow *handle, int count, const char **paths) {
|
||||
Window *window = (Window *)glfwGetWindowUserPointer(handle);
|
||||
window->fileDrop(count, paths);
|
||||
}
|
||||
|
||||
void glfwCloseCallback(GLFWwindow* handle) {
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
void glfwCloseCallback(GLFWwindow *handle) {
|
||||
Window *window = (Window *)glfwGetWindowUserPointer(handle);
|
||||
window->close();
|
||||
}
|
||||
|
||||
void glfwFramebufferResizeCallback(GLFWwindow* handle, int width, int height) {
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
void glfwFramebufferResizeCallback(GLFWwindow *handle, int width, int height) {
|
||||
Window *window = (Window *)glfwGetWindowUserPointer(handle);
|
||||
window->resize(width, height);
|
||||
}
|
||||
|
||||
Window::Window(PGraphics graphics, const WindowCreateInfo& createInfo) : graphics(graphics), preferences(createInfo) {
|
||||
glfwSetErrorCallback([](int, const char* description) { std::cout << description << std::endl; });
|
||||
Window::Window(PGraphics graphics, const WindowCreateInfo &createInfo)
|
||||
: graphics(graphics), preferences(createInfo) {
|
||||
glfwSetErrorCallback([](int, const char *description) {
|
||||
std::cout << description << std::endl;
|
||||
});
|
||||
float xscale = 1, yscale = 1;
|
||||
glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &xscale, &yscale);
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
GLFWwindow* handle =
|
||||
glfwCreateWindow(createInfo.width / xscale, createInfo.height / yscale, createInfo.title, nullptr, nullptr);
|
||||
GLFWwindow *handle =
|
||||
glfwCreateWindow(createInfo.width / xscale, createInfo.height / yscale,
|
||||
createInfo.title, nullptr, nullptr);
|
||||
windowHandle = handle;
|
||||
glfwSetWindowUserPointer(handle, this);
|
||||
|
||||
@@ -89,12 +96,14 @@ Window::Window(PGraphics graphics, const WindowCreateInfo& createInfo) : graphic
|
||||
metalWindow.contentView.wantsLayer = YES;
|
||||
}
|
||||
|
||||
Window::~Window() { glfwDestroyWindow(static_cast<GLFWwindow*>(windowHandle)); }
|
||||
Window::~Window() {
|
||||
glfwDestroyWindow(static_cast<GLFWwindow *>(windowHandle));
|
||||
}
|
||||
|
||||
void Window::pollInput() { glfwPollEvents(); }
|
||||
|
||||
void Window::beginFrame() {
|
||||
drawable = (__bridge CA::MetalDrawable*)[metalLayer nextDrawable];
|
||||
drawable = (__bridge CA::MetalDrawable *)[metalLayer nextDrawable];
|
||||
createBackBuffer();
|
||||
}
|
||||
|
||||
@@ -108,33 +117,51 @@ void Window::onWindowCloseEvent() {}
|
||||
|
||||
Gfx::PTexture2D Window::getBackBuffer() const { return PTexture2D(backBuffer); }
|
||||
|
||||
void Window::setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback) { keyCallback = callback; }
|
||||
void Window::setKeyCallback(
|
||||
std::function<void(KeyCode, InputAction, KeyModifier)> callback) {
|
||||
keyCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setMouseMoveCallback(std::function<void(double, double)> callback) { mouseMoveCallback = callback; }
|
||||
void Window::setMouseMoveCallback(
|
||||
std::function<void(double, double)> callback) {
|
||||
mouseMoveCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback) {
|
||||
void Window::setMouseButtonCallback(
|
||||
std::function<void(MouseButton, InputAction, KeyModifier)> callback) {
|
||||
mouseButtonCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setScrollCallback(std::function<void(double, double)> callback) { scrollCallback = callback; }
|
||||
void Window::setScrollCallback(std::function<void(double, double)> callback) {
|
||||
scrollCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setFileCallback(std::function<void(int, const char**)> callback) { fileCallback = callback; }
|
||||
void Window::setFileCallback(std::function<void(int, const char **)> callback) {
|
||||
fileCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setCloseCallback(std::function<void()> callback) { closeCallback = callback; }
|
||||
void Window::setCloseCallback(std::function<void()> callback) {
|
||||
closeCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setResizeCallback(std::function<void(uint32, uint32)> callback) { resizeCallback = callback; }
|
||||
void Window::setResizeCallback(std::function<void(uint32, uint32)> callback) {
|
||||
resizeCallback = callback;
|
||||
}
|
||||
|
||||
void Window::keyPress(KeyCode code, InputAction action, KeyModifier modifier) { keyCallback(code, action, modifier); }
|
||||
void Window::keyPress(KeyCode code, InputAction action, KeyModifier modifier) {
|
||||
keyCallback(code, action, modifier);
|
||||
}
|
||||
|
||||
void Window::mouseMove(double x, double y) { mouseMoveCallback(x, y); }
|
||||
|
||||
void Window::mouseButton(MouseButton button, InputAction action, KeyModifier modifier) {
|
||||
void Window::mouseButton(MouseButton button, InputAction action,
|
||||
KeyModifier modifier) {
|
||||
mouseButtonCallback(button, action, modifier);
|
||||
}
|
||||
|
||||
void Window::scroll(double x, double y) { scrollCallback(x, y); }
|
||||
|
||||
void Window::fileDrop(int num, const char** files) { fileCallback(num, files); }
|
||||
void Window::fileDrop(int num, const char **files) { fileCallback(num, files); }
|
||||
|
||||
void Window::close() { closeCallback(); }
|
||||
|
||||
@@ -149,28 +176,31 @@ void Window::resize(int width, int height) {
|
||||
framebufferWidth = width;
|
||||
framebufferHeight = height;
|
||||
// Deallocate the textures if they have been created
|
||||
drawable = (__bridge CA::MetalDrawable*)[[metalLayer nextDrawable] autorelease];
|
||||
drawable =
|
||||
(__bridge CA::MetalDrawable *)[[metalLayer nextDrawable] autorelease];
|
||||
createBackBuffer();
|
||||
resizeCallback(width, height);
|
||||
}
|
||||
|
||||
void Window::createBackBuffer() {
|
||||
MTL::Texture* buf = drawable->texture();
|
||||
backBuffer = new Texture2D(graphics,
|
||||
TextureCreateInfo{
|
||||
.width = static_cast<uint32>(buf->width()),
|
||||
.height = static_cast<uint32>(buf->height()),
|
||||
.depth = static_cast<uint32>(buf->depth()),
|
||||
.elements = static_cast<uint32>(buf->arrayLength()),
|
||||
.mipLevels = static_cast<uint32>(buf->mipmapLevelCount()),
|
||||
.format = cast(buf->pixelFormat()),
|
||||
.usage = MTL::TextureUsageRenderTarget,
|
||||
.samples = static_cast<uint32>(buf->sampleCount()),
|
||||
},
|
||||
buf);
|
||||
MTL::Texture *buf = drawable->texture();
|
||||
backBuffer = new Texture2D(
|
||||
graphics,
|
||||
TextureCreateInfo{
|
||||
.width = static_cast<uint32>(buf->width()),
|
||||
.height = static_cast<uint32>(buf->height()),
|
||||
.depth = static_cast<uint32>(buf->depth()),
|
||||
.elements = static_cast<uint32>(buf->arrayLength()),
|
||||
.mipLevels = static_cast<uint32>(buf->mipmapLevelCount()),
|
||||
.format = cast(buf->pixelFormat()),
|
||||
.usage = MTL::TextureUsageRenderTarget,
|
||||
.samples = static_cast<uint32>(buf->sampleCount()),
|
||||
},
|
||||
buf);
|
||||
}
|
||||
|
||||
Viewport::Viewport(PWindow owner, const ViewportCreateInfo& createInfo) : Gfx::Viewport(owner, createInfo) {
|
||||
Viewport::Viewport(PWindow owner, const ViewportCreateInfo &createInfo)
|
||||
: Gfx::Viewport(owner, createInfo) {
|
||||
viewport.width = sizeX;
|
||||
viewport.height = sizeY;
|
||||
viewport.originX = offsetX;
|
||||
|
||||
@@ -3,39 +3,18 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
VertexInput::VertexInput(VertexInputStateCreateInfo createInfo)
|
||||
: createInfo(createInfo)
|
||||
{
|
||||
}
|
||||
VertexInput::VertexInput(VertexInputStateCreateInfo createInfo) : createInfo(createInfo) {}
|
||||
|
||||
VertexInput::~VertexInput()
|
||||
{
|
||||
}
|
||||
VertexInput::~VertexInput() {}
|
||||
|
||||
GraphicsPipeline::GraphicsPipeline(PPipelineLayout layout)
|
||||
: layout(layout)
|
||||
{
|
||||
}
|
||||
GraphicsPipeline::GraphicsPipeline(PPipelineLayout layout) : layout(layout) {}
|
||||
|
||||
GraphicsPipeline::~GraphicsPipeline()
|
||||
{
|
||||
}
|
||||
GraphicsPipeline::~GraphicsPipeline() {}
|
||||
|
||||
PPipelineLayout GraphicsPipeline::getPipelineLayout() const
|
||||
{
|
||||
return layout;
|
||||
}
|
||||
PPipelineLayout GraphicsPipeline::getPipelineLayout() const { return layout; }
|
||||
|
||||
ComputePipeline::ComputePipeline(PPipelineLayout layout)
|
||||
: layout(layout)
|
||||
{
|
||||
}
|
||||
ComputePipeline::ComputePipeline(PPipelineLayout layout) : layout(layout) {}
|
||||
|
||||
ComputePipeline::~ComputePipeline()
|
||||
{
|
||||
}
|
||||
ComputePipeline::~ComputePipeline() {}
|
||||
|
||||
PPipelineLayout ComputePipeline::getPipelineLayout() const
|
||||
{
|
||||
return layout;
|
||||
}
|
||||
PPipelineLayout ComputePipeline::getPipelineLayout() const { return layout; }
|
||||
|
||||
@@ -1,40 +1,39 @@
|
||||
#pragma once
|
||||
#include "Enums.h"
|
||||
#include "Descriptor.h"
|
||||
#include "Enums.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Gfx
|
||||
{
|
||||
class VertexInput
|
||||
{
|
||||
public:
|
||||
|
||||
namespace Seele {
|
||||
namespace Gfx {
|
||||
class VertexInput {
|
||||
public:
|
||||
VertexInput(VertexInputStateCreateInfo createInfo);
|
||||
virtual ~VertexInput();
|
||||
const VertexInputStateCreateInfo& getInfo() const { return createInfo; }
|
||||
private:
|
||||
|
||||
private:
|
||||
VertexInputStateCreateInfo createInfo;
|
||||
};
|
||||
class GraphicsPipeline
|
||||
{
|
||||
public:
|
||||
class GraphicsPipeline {
|
||||
public:
|
||||
GraphicsPipeline(PPipelineLayout layout);
|
||||
virtual ~GraphicsPipeline();
|
||||
PPipelineLayout getPipelineLayout() const;
|
||||
protected:
|
||||
|
||||
protected:
|
||||
PPipelineLayout layout;
|
||||
};
|
||||
DEFINE_REF(GraphicsPipeline)
|
||||
|
||||
class ComputePipeline
|
||||
{
|
||||
public:
|
||||
class ComputePipeline {
|
||||
public:
|
||||
ComputePipeline(PPipelineLayout layout);
|
||||
virtual ~ComputePipeline();
|
||||
PPipelineLayout getPipelineLayout() const;
|
||||
protected:
|
||||
|
||||
protected:
|
||||
PPipelineLayout layout;
|
||||
};
|
||||
DEFINE_REF(ComputePipeline)
|
||||
}
|
||||
}
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
|
||||
@@ -2,14 +2,10 @@
|
||||
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
BottomLevelAS::BottomLevelAS()
|
||||
{}
|
||||
BottomLevelAS::BottomLevelAS() {}
|
||||
|
||||
BottomLevelAS::~BottomLevelAS()
|
||||
{}
|
||||
BottomLevelAS::~BottomLevelAS() {}
|
||||
|
||||
TopLevelAS::TopLevelAS()
|
||||
{}
|
||||
TopLevelAS::TopLevelAS() {}
|
||||
|
||||
TopLevelAS::~TopLevelAS()
|
||||
{}
|
||||
TopLevelAS::~TopLevelAS() {}
|
||||
@@ -1,25 +1,23 @@
|
||||
#pragma once
|
||||
#include "Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Gfx
|
||||
{
|
||||
class BottomLevelAS
|
||||
{
|
||||
public:
|
||||
namespace Seele {
|
||||
namespace Gfx {
|
||||
class BottomLevelAS {
|
||||
public:
|
||||
BottomLevelAS();
|
||||
~BottomLevelAS();
|
||||
private:
|
||||
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(BottomLevelAS)
|
||||
class TopLevelAS
|
||||
{
|
||||
public:
|
||||
class TopLevelAS {
|
||||
public:
|
||||
TopLevelAS();
|
||||
~TopLevelAS();
|
||||
private:
|
||||
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(TopLevelAS)
|
||||
}
|
||||
}
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
@@ -1,26 +1,25 @@
|
||||
#include "BasePass.h"
|
||||
#include "Actor/CameraActor.h"
|
||||
#include "Component/Camera.h"
|
||||
#include "Component/Mesh.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/Shader.h"
|
||||
#include "Window/Window.h"
|
||||
#include "Component/Camera.h"
|
||||
#include "Component/Mesh.h"
|
||||
#include "Actor/CameraActor.h"
|
||||
#include "Graphics/StaticMeshVertexData.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "Math/Vector.h"
|
||||
#include "RenderGraph.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "Graphics/StaticMeshVertexData.h"
|
||||
#include "Window/Window.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
extern bool useViewCulling;
|
||||
|
||||
BasePass::BasePass(Gfx::PGraphics graphics, PScene scene)
|
||||
: RenderPass(graphics, scene)
|
||||
{
|
||||
BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {
|
||||
basePassLayout = graphics->createPipelineLayout("BasePassLayout");
|
||||
|
||||
basePassLayout->addDescriptorLayout(viewParamsLayout);
|
||||
@@ -28,9 +27,15 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene)
|
||||
|
||||
lightCullingLayout = graphics->createDescriptorLayout("pLightCullingData");
|
||||
// oLightIndexList
|
||||
lightCullingLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, });
|
||||
lightCullingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
// oLightGrid
|
||||
lightCullingLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE, });
|
||||
lightCullingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 1,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
});
|
||||
lightCullingLayout->create();
|
||||
|
||||
basePassLayout->addDescriptorLayout(lightCullingLayout);
|
||||
@@ -38,44 +43,38 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene)
|
||||
.stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT,
|
||||
.offset = 0,
|
||||
.size = sizeof(VertexData::DrawCallOffsets),
|
||||
});
|
||||
});
|
||||
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
graphics->getShaderCompiler()->registerRenderPass("BasePass", Gfx::PassConfig {
|
||||
.baseLayout = basePassLayout,
|
||||
.taskFile = "DrawListTask",
|
||||
.mainFile = "DrawListMesh",
|
||||
.fragmentFile = "BasePass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = true,
|
||||
.hasTaskShader = true,
|
||||
.useMaterial = true,
|
||||
.useVisibility = false,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics->getShaderCompiler()->registerRenderPass("BasePass", Gfx::PassConfig {
|
||||
.baseLayout = basePassLayout,
|
||||
.taskFile = "",
|
||||
.mainFile = "LegacyPass",
|
||||
.fragmentFile = "BasePass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = false,
|
||||
.hasTaskShader = false,
|
||||
.useMaterial = true,
|
||||
.useVisibility = false,
|
||||
});
|
||||
if (graphics->supportMeshShading()) {
|
||||
graphics->getShaderCompiler()->registerRenderPass("BasePass", Gfx::PassConfig{
|
||||
.baseLayout = basePassLayout,
|
||||
.taskFile = "DrawListTask",
|
||||
.mainFile = "DrawListMesh",
|
||||
.fragmentFile = "BasePass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = true,
|
||||
.hasTaskShader = true,
|
||||
.useMaterial = true,
|
||||
.useVisibility = false,
|
||||
});
|
||||
} else {
|
||||
graphics->getShaderCompiler()->registerRenderPass("BasePass", Gfx::PassConfig{
|
||||
.baseLayout = basePassLayout,
|
||||
.taskFile = "",
|
||||
.mainFile = "LegacyPass",
|
||||
.fragmentFile = "BasePass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = false,
|
||||
.hasTaskShader = false,
|
||||
.useMaterial = true,
|
||||
.useVisibility = false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
BasePass::~BasePass()
|
||||
{
|
||||
}
|
||||
BasePass::~BasePass() {}
|
||||
|
||||
void BasePass::beginFrame(const Component::Camera& cam)
|
||||
{
|
||||
void BasePass::beginFrame(const Component::Camera& cam) {
|
||||
RenderPass::beginFrame(cam);
|
||||
|
||||
lightCullingLayout->reset();
|
||||
@@ -83,8 +82,7 @@ void BasePass::beginFrame(const Component::Camera& cam)
|
||||
transparentCulling = lightCullingLayout->allocateDescriptorSet();
|
||||
}
|
||||
|
||||
void BasePass::render()
|
||||
{
|
||||
void BasePass::render() {
|
||||
opaqueCulling->updateBuffer(0, oLightIndexList);
|
||||
opaqueCulling->updateTexture(1, oLightGrid);
|
||||
transparentCulling->updateBuffer(0, tLightIndexList);
|
||||
@@ -97,14 +95,12 @@ void BasePass::render()
|
||||
|
||||
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("BasePass");
|
||||
permutation.setViewCulling(useViewCulling);
|
||||
for (VertexData* vertexData : VertexData::getList())
|
||||
{
|
||||
for (VertexData* vertexData : VertexData::getList()) {
|
||||
vertexData->getInstanceDataSet()->updateBuffer(6, cullingBuffer);
|
||||
vertexData->getInstanceDataSet()->writeChanges();
|
||||
permutation.setVertexData(vertexData->getTypeName());
|
||||
const auto& materials = vertexData->getMaterialData();
|
||||
for (const auto& materialData : materials)
|
||||
{
|
||||
for (const auto& materialData : materials) {
|
||||
// material not used for any active meshes, skip
|
||||
if (materialData.instances.size() == 0)
|
||||
continue;
|
||||
@@ -124,43 +120,46 @@ void BasePass::render()
|
||||
|
||||
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
||||
assert(collection != nullptr);
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
if (graphics->supportMeshShading()) {
|
||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||
.taskShader = collection->taskShader,
|
||||
.meshShader = collection->meshShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState = {
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
|
||||
},
|
||||
.colorBlend = {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
.multisampleState =
|
||||
{
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState =
|
||||
{
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
||||
.vertexShader = collection->vertexShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState = {
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
|
||||
},
|
||||
.colorBlend = {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
.multisampleState =
|
||||
{
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState =
|
||||
{
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
@@ -170,21 +169,18 @@ void BasePass::render()
|
||||
command->bindDescriptor(vertexData->getInstanceDataSet());
|
||||
command->bindDescriptor(scene->getLightEnvironment()->getDescriptorSet());
|
||||
command->bindDescriptor(opaqueCulling);
|
||||
for (const auto& drawCall : materialData.instances)
|
||||
{
|
||||
for (const auto& drawCall : materialData.instances) {
|
||||
command->bindDescriptor(drawCall.materialInstance->getDescriptorSet());
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &drawCall.offsets);
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0,
|
||||
sizeof(VertexData::DrawCallOffsets), &drawCall.offsets);
|
||||
if (graphics->supportMeshShading()) {
|
||||
command->drawMesh(drawCall.instanceMeshData.size(), 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
||||
for (const auto& meshData : drawCall.instanceMeshData)
|
||||
{
|
||||
for (const auto& meshData : drawCall.instanceMeshData) {
|
||||
// all meshlets of a mesh share the same indices offset
|
||||
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), 0);
|
||||
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex,
|
||||
vertexData->getIndicesOffset(meshData.meshletOffset), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,14 +191,14 @@ void BasePass::render()
|
||||
graphics->executeCommands(std::move(commands));
|
||||
graphics->endRenderPass();
|
||||
// Sync color write with next pass/swapchain present
|
||||
//colorAttachment.getTexture()->pipelineBarrier(
|
||||
// colorAttachment.getTexture()->pipelineBarrier(
|
||||
// Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
// Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
|
||||
//);
|
||||
// Sync depth with next pass/next frame
|
||||
//depthAttachment.getTexture()->pipelineBarrier(
|
||||
// depthAttachment.getTexture()->pipelineBarrier(
|
||||
// Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
// Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
|
||||
@@ -210,20 +206,15 @@ void BasePass::render()
|
||||
//);
|
||||
}
|
||||
|
||||
void BasePass::endFrame()
|
||||
{
|
||||
}
|
||||
void BasePass::endFrame() {}
|
||||
|
||||
void BasePass::publishOutputs()
|
||||
{
|
||||
colorAttachment = Gfx::RenderTargetAttachment(viewport,
|
||||
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
void BasePass::publishOutputs() {
|
||||
colorAttachment = Gfx::RenderTargetAttachment(viewport, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
resources->registerRenderPassOutput("BASEPASS_COLOR", colorAttachment);
|
||||
}
|
||||
|
||||
void BasePass::createRenderPass()
|
||||
{
|
||||
void BasePass::createRenderPass() {
|
||||
cullingBuffer = resources->requestBuffer("CULLINGBUFFER");
|
||||
|
||||
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
|
||||
@@ -231,7 +222,7 @@ void BasePass::createRenderPass()
|
||||
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
|
||||
depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||
.colorAttachments = { colorAttachment },
|
||||
.colorAttachments = {colorAttachment},
|
||||
.depthAttachment = depthAttachment,
|
||||
};
|
||||
Array<Gfx::SubPassDependency> dependency = {
|
||||
@@ -240,16 +231,20 @@ void BasePass::createRenderPass()
|
||||
.dstSubpass = 0,
|
||||
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
{
|
||||
.srcSubpass = 0,
|
||||
.dstSubpass = ~0U,
|
||||
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
};
|
||||
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport);
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
#include "MinimalEngine.h"
|
||||
#include "RenderPass.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Seele {
|
||||
DECLARE_REF(CameraActor)
|
||||
class BasePass : public RenderPass
|
||||
{
|
||||
public:
|
||||
class BasePass : public RenderPass {
|
||||
public:
|
||||
BasePass(Gfx::PGraphics graphics, PScene scene);
|
||||
BasePass(BasePass&&) = default;
|
||||
BasePass& operator=(BasePass&&) = default;
|
||||
@@ -17,7 +15,8 @@ public:
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
private:
|
||||
|
||||
private:
|
||||
Gfx::RenderTargetAttachment colorAttachment;
|
||||
Gfx::RenderTargetAttachment depthAttachment;
|
||||
Gfx::RenderTargetAttachment visibilityAttachment;
|
||||
@@ -25,7 +24,7 @@ private:
|
||||
Gfx::PShaderBuffer tLightIndexList;
|
||||
Gfx::PTexture2D oLightGrid;
|
||||
Gfx::PTexture2D tLightGrid;
|
||||
|
||||
|
||||
Gfx::PDescriptorSet opaqueCulling;
|
||||
Gfx::PDescriptorSet transparentCulling;
|
||||
|
||||
|
||||
@@ -6,9 +6,7 @@ using namespace Seele;
|
||||
extern bool usePositionOnly;
|
||||
extern bool useViewCulling;
|
||||
|
||||
CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene)
|
||||
: RenderPass(graphics, scene)
|
||||
{
|
||||
CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {
|
||||
depthPrepassLayout = graphics->createPipelineLayout("CachedDepthLayout");
|
||||
depthPrepassLayout->addDescriptorLayout(viewParamsLayout);
|
||||
depthPrepassLayout->addPushConstants(Gfx::SePushConstantRange{
|
||||
@@ -16,55 +14,45 @@ CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene)
|
||||
.offset = 0,
|
||||
.size = sizeof(VertexData::DrawCallOffsets),
|
||||
});
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
if (graphics->supportMeshShading()) {
|
||||
graphics->getShaderCompiler()->registerRenderPass("CachedDepthPass", Gfx::PassConfig{
|
||||
.baseLayout = depthPrepassLayout,
|
||||
.taskFile = "DrawListTask",
|
||||
.mainFile = "DrawListMesh",
|
||||
.fragmentFile = "VisibilityPass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = true,
|
||||
.hasTaskShader = true,
|
||||
.useMaterial = false,
|
||||
.useVisibility = true,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
.baseLayout = depthPrepassLayout,
|
||||
.taskFile = "DrawListTask",
|
||||
.mainFile = "DrawListMesh",
|
||||
.fragmentFile = "VisibilityPass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = true,
|
||||
.hasTaskShader = true,
|
||||
.useMaterial = false,
|
||||
.useVisibility = true,
|
||||
});
|
||||
} else {
|
||||
graphics->getShaderCompiler()->registerRenderPass("CachedDepthPass", Gfx::PassConfig{
|
||||
.baseLayout = depthPrepassLayout,
|
||||
.taskFile = "",
|
||||
.mainFile = "LegacyPass",
|
||||
.fragmentFile = "VisibilityPass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = false,
|
||||
.hasTaskShader = false,
|
||||
.useMaterial = false,
|
||||
.useVisibility = true,
|
||||
});
|
||||
.baseLayout = depthPrepassLayout,
|
||||
.taskFile = "",
|
||||
.mainFile = "LegacyPass",
|
||||
.fragmentFile = "VisibilityPass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = false,
|
||||
.hasTaskShader = false,
|
||||
.useMaterial = false,
|
||||
.useVisibility = true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
CachedDepthPass::~CachedDepthPass()
|
||||
{
|
||||
}
|
||||
CachedDepthPass::~CachedDepthPass() {}
|
||||
|
||||
void CachedDepthPass::beginFrame(const Component::Camera &cam)
|
||||
{
|
||||
RenderPass::beginFrame(cam);
|
||||
}
|
||||
void CachedDepthPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); }
|
||||
|
||||
void CachedDepthPass::render()
|
||||
{
|
||||
void CachedDepthPass::render() {
|
||||
graphics->beginRenderPass(renderPass);
|
||||
Array<Gfx::ORenderCommand> commands;
|
||||
|
||||
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("CachedDepthPass");
|
||||
permutation.setPositionOnly(usePositionOnly);
|
||||
permutation.setViewCulling(useViewCulling);
|
||||
for (VertexData *vertexData : VertexData::getList())
|
||||
{
|
||||
for (VertexData* vertexData : VertexData::getList()) {
|
||||
permutation.setVertexData(vertexData->getTypeName());
|
||||
vertexData->getInstanceDataSet()->updateBuffer(6, cullingBuffer);
|
||||
vertexData->getInstanceDataSet()->writeChanges();
|
||||
@@ -79,45 +67,48 @@ void CachedDepthPass::render()
|
||||
Gfx::ORenderCommand command = graphics->createRenderCommand("DepthRender");
|
||||
command->setViewport(viewport);
|
||||
|
||||
const Gfx::ShaderCollection *collection = graphics->getShaderCompiler()->findShaders(id);
|
||||
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
||||
assert(collection != nullptr);
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
if (graphics->supportMeshShading()) {
|
||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||
.taskShader = collection->taskShader,
|
||||
.meshShader = collection->meshShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState = {
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend = {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
.multisampleState =
|
||||
{
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState =
|
||||
{
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
||||
.vertexShader = collection->vertexShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState = {
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend = {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
.multisampleState =
|
||||
{
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState =
|
||||
{
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
@@ -126,27 +117,23 @@ void CachedDepthPass::render()
|
||||
command->bindDescriptor(vertexData->getVertexDataSet());
|
||||
command->bindDescriptor(vertexData->getInstanceDataSet());
|
||||
uint32 offset = 0;
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &offset);
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets),
|
||||
&offset);
|
||||
if (graphics->supportMeshShading()) {
|
||||
command->drawMesh(vertexData->getNumInstances(), 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto &materials = vertexData->getMaterialData();
|
||||
for (const auto &materialData : materials)
|
||||
{
|
||||
} else {
|
||||
const auto& materials = vertexData->getMaterialData();
|
||||
for (const auto& materialData : materials) {
|
||||
// material not used for any active meshes, skip
|
||||
if (materialData.instances.size() == 0)
|
||||
continue;
|
||||
for (const auto &drawCall : materialData.instances)
|
||||
{
|
||||
for (const auto& drawCall : materialData.instances) {
|
||||
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
||||
uint32 inst = drawCall.offsets.instanceOffset;
|
||||
for (const auto &meshData : drawCall.instanceMeshData)
|
||||
{
|
||||
for (const auto& meshData : drawCall.instanceMeshData) {
|
||||
// all meshlets of a mesh share the same indices offset
|
||||
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), inst++);
|
||||
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex,
|
||||
vertexData->getIndicesOffset(meshData.meshletOffset), inst++);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,25 +144,22 @@ void CachedDepthPass::render()
|
||||
graphics->executeCommands(std::move(commands));
|
||||
graphics->endRenderPass();
|
||||
// Sync depth read/write with depth pass depth read
|
||||
//depthBuffer->pipelineBarrier(
|
||||
// depthBuffer->pipelineBarrier(
|
||||
// Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
// Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
|
||||
// sync visibility write with depth pass visibility write
|
||||
//visibilityBuffer->pipelineBarrier(
|
||||
// visibilityBuffer->pipelineBarrier(
|
||||
// Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
// Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
||||
}
|
||||
|
||||
void CachedDepthPass::endFrame()
|
||||
{
|
||||
}
|
||||
void CachedDepthPass::endFrame() {}
|
||||
|
||||
void CachedDepthPass::publishOutputs()
|
||||
{
|
||||
void CachedDepthPass::publishOutputs() {
|
||||
// If we render to a part of an image, the depth buffer itself must
|
||||
// still match the size of the whole image or their coordinate systems go out of sync
|
||||
TextureCreateInfo depthBufferInfo = {
|
||||
@@ -186,8 +170,7 @@ void CachedDepthPass::publishOutputs()
|
||||
};
|
||||
depthBuffer = graphics->createTexture2D(depthBufferInfo);
|
||||
depthAttachment =
|
||||
Gfx::RenderTargetAttachment(depthBuffer,
|
||||
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
Gfx::RenderTargetAttachment(depthBuffer, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
resources->registerRenderPassOutput("DEPTHPREPASS_DEPTH", depthAttachment);
|
||||
|
||||
@@ -199,14 +182,12 @@ void CachedDepthPass::publishOutputs()
|
||||
};
|
||||
visibilityBuffer = graphics->createTexture2D(visibilityInfo);
|
||||
visibilityAttachment =
|
||||
Gfx::RenderTargetAttachment(visibilityBuffer,
|
||||
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
Gfx::RenderTargetAttachment(visibilityBuffer, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
resources->registerRenderPassOutput("VISIBILITY", visibilityAttachment);
|
||||
}
|
||||
|
||||
void CachedDepthPass::createRenderPass()
|
||||
{
|
||||
void CachedDepthPass::createRenderPass() {
|
||||
cullingBuffer = resources->requestBuffer("CULLINGBUFFER");
|
||||
|
||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||
@@ -219,16 +200,20 @@ void CachedDepthPass::createRenderPass()
|
||||
.dstSubpass = 0,
|
||||
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
{
|
||||
.srcSubpass = 0,
|
||||
.dstSubpass = ~0U,
|
||||
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
};
|
||||
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport);
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
#pragma once
|
||||
#include "RenderPass.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class CachedDepthPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
namespace Seele {
|
||||
class CachedDepthPass : public RenderPass {
|
||||
public:
|
||||
CachedDepthPass(Gfx::PGraphics graphics, PScene scene);
|
||||
CachedDepthPass(CachedDepthPass&&) = default;
|
||||
CachedDepthPass& operator=(CachedDepthPass&&) = default;
|
||||
@@ -15,14 +13,15 @@ public:
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
private:
|
||||
|
||||
private:
|
||||
Gfx::RenderTargetAttachment depthAttachment;
|
||||
Gfx::RenderTargetAttachment visibilityAttachment;
|
||||
Gfx::OTexture2D depthBuffer;
|
||||
Gfx::OTexture2D visibilityBuffer;
|
||||
Gfx::OPipelineLayout depthPrepassLayout;
|
||||
|
||||
|
||||
Gfx::PShaderBuffer cullingBuffer;
|
||||
};
|
||||
DEFINE_REF(CachedDepthPass)
|
||||
}
|
||||
} // namespace Seele
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user