Redo of render paths

This commit is contained in:
Dynamitos
2020-06-02 11:46:18 +02:00
parent bb5b48698a
commit 356e6058fe
121 changed files with 3890 additions and 572 deletions
+56
View File
@@ -3,9 +3,65 @@
using namespace Seele;
Asset::Asset()
: fullPath("")
, name("")
, parentDir("")
, extension("")
, status(Status::Uninitialized)
{
}
Asset::Asset(const std::filesystem::path& path)
: fullPath(std::filesystem::absolute(path))
, status(Status::Uninitialized)
{
fullPath.make_preferred();
parentDir = fullPath.parent_path();
name = fullPath.stem();
extension = fullPath.extension();
}
Asset::Asset(const std::string &fullPath)
: Asset(std::filesystem::path(fullPath))
{
}
Asset::Asset(const std::string &directory, const std::string &fileName)
: Asset(std::filesystem::path(directory + fileName))
{
}
Asset::~Asset()
{
}
std::ifstream &Asset::getReadStream()
{
if(inStream.is_open())
{
return inStream;
}
inStream.open(fullPath);
return inStream;
}
std::ofstream &Asset::getWriteStream()
{
if(outStream.is_open())
{
return outStream;
}
outStream.open(fullPath);
return outStream;
}
std::string Asset::getFileName()
{
return name.generic_string();
}
std::string Asset::getFullPath()
{
return fullPath.generic_string();
}
std::string Asset::getExtension()
{
return extension.generic_string();
}
+38 -1
View File
@@ -6,10 +6,47 @@ namespace Seele
class Asset
{
public:
enum class Status
{
Uninitialized,
Loading,
Ready
};
Asset();
Asset(const std::filesystem::path& path);
Asset(const std::string& directory, const std::string& name);
Asset(const std::string& fullPath);
virtual ~Asset();
std::ifstream& getReadStream();
std::ofstream& getWriteStream();
// returns the name of the file, without extension
std::string getFileName();
// returns the full absolute path, from root to extension
std::string getFullPath();
// returns the file extension, without preceding dot
std::string getExtension();
inline Status getStatus()
{
std::scoped_lock lck(lock);
return status;
}
inline void setStatus(Status status)
{
std::scoped_lock lck(lock);
this->status = status;
}
protected:
std::mutex lock;
private:
Status status;
std::filesystem::path fullPath;
std::filesystem::path parentDir;
std::filesystem::path name;
std::filesystem::path extension;
uint32 byteSize;
std::ifstream inStream;
std::ofstream outStream;
};
DEFINE_REF(Asset);
} // namespace Seele
+89
View File
@@ -0,0 +1,89 @@
#include "AssetRegistry.h"
#include "MeshAsset.h"
#include "TextureAsset.h"
#include "TextureLoader.h"
#include "MaterialLoader.h"
#include "MeshLoader.h"
#include "Material/Material.h"
#include "Graphics/Graphics.h"
#include "graphics/WindowManager.h"
using namespace Seele;
AssetRegistry::~AssetRegistry()
{
}
void AssetRegistry::init(const std::string& rootFolder)
{
get().init(rootFolder, WindowManager::getGraphics());
}
void AssetRegistry::importFile(const std::string &filePath)
{
std::string extension = filePath.substr(filePath.find_last_of(".") + 1);
std::cout << extension << std::endl;
if (extension.compare("fbx") == 0
|| extension.compare("obj") == 0)
{
get().registerMesh(filePath);
}
if (extension.compare("png") == 0
|| extension.compare("jpg") == 0)
{
get().registerTexture(filePath);
}
if (extension.compare("semat") == 0)
{
get().registerMaterial(filePath);
}
}
PMeshAsset AssetRegistry::findMesh(const std::string &filePath)
{
return get().meshes[filePath];
}
PMaterialAsset AssetRegistry::findMaterial(const std::string &filePath)
{
return get().materials[filePath];
}
PTextureAsset AssetRegistry::findTexture(const std::string &filePath)
{
return get().textures[filePath];
}
AssetRegistry &AssetRegistry::get()
{
static AssetRegistry instance;
return instance;
}
AssetRegistry::AssetRegistry()
{
}
void AssetRegistry::init(const std::string &rootFolder, Gfx::PGraphics graphics)
{
AssetRegistry &reg = get();
reg.rootFolder = rootFolder;
reg.meshLoader = new MeshLoader(graphics);
reg.textureLoader = new TextureLoader(graphics);
reg.materialLoader = new MaterialLoader(graphics);
}
void AssetRegistry::registerMesh(const std::string &filePath)
{
meshLoader->importAsset(filePath);
}
void AssetRegistry::registerTexture(const std::string &filePath)
{
textureLoader->importAsset(filePath);
}
void AssetRegistry::registerMaterial(const std::string &filePath)
{
materialLoader->queueAsset(filePath);
}
+47
View File
@@ -0,0 +1,47 @@
#pragma once
#include "MinimalEngine.h"
#include "Asset.h"
#include <string>
namespace Seele
{
DECLARE_REF(TextureLoader);
DECLARE_REF(MeshLoader);
DECLARE_REF(MaterialLoader);
DECLARE_REF(TextureAsset);
DECLARE_REF(MeshAsset);
DECLARE_REF(MaterialAsset);
DECLARE_NAME_REF(Gfx, Graphics);
class AssetRegistry
{
public:
~AssetRegistry();
static void init(const std::string& rootFolder);
static void importFile(const std::string& filePath);
static PMeshAsset findMesh(const std::string& filePath);
static PTextureAsset findTexture(const std::string& filePath);
static PMaterialAsset findMaterial(const std::string& filePath);
private:
static AssetRegistry& get();
AssetRegistry();
void init(const std::string& rootFolder, Gfx::PGraphics graphics);
void registerMesh(const std::string& filePath);
void registerTexture(const std::string& filePath);
void registerMaterial(const std::string& filePath);
std::string rootFolder;
Map<std::string, PTextureAsset> textures;
Map<std::string, PMeshAsset> meshes;
Map<std::string, PMaterialAsset> materials;
UPTextureLoader textureLoader;
UPMeshLoader meshLoader;
UPMaterialLoader materialLoader;
friend class TextureLoader;
friend class MaterialLoader;
friend class MeshLoader;
};
}
+12 -2
View File
@@ -2,5 +2,15 @@ target_sources(SeeleEngine
PRIVATE
Asset.h
Asset.cpp
FileAsset.h
FileAsset.cpp)
AssetRegistry.h
AssetRegistry.cpp
MaterialLoader.h
MaterialLoader.cpp
MeshAsset.h
MeshAsset.cpp
MeshLoader.h
MeshLoader.cpp
TextureAsset.h
TextureAsset.cpp
TextureLoader.h
TextureLoader.cpp)
-62
View File
@@ -1,62 +0,0 @@
#include "FileAsset.h"
using namespace Seele;
FileAsset::FileAsset()
: path("")
, name("")
{
}
FileAsset::FileAsset(const std::string &fullPath)
: path(fullPath)
{
name = fullPath.substr(fullPath.find_last_of('\\')+1);
}
FileAsset::FileAsset(const std::string &directory, const std::string &name)
: path(directory+name)
, name(name)
{
}
FileAsset::~FileAsset()
{
}
std::ifstream &FileAsset::getReadStream()
{
if(inStream.is_open())
{
return inStream;
}
inStream.open(path);
return inStream;
}
std::ofstream &FileAsset::getWriteStream()
{
if(outStream.is_open())
{
return outStream;
}
outStream.open(path);
return outStream;
}
void FileAsset::rename(const std::string& newName)
{
if(inStream.is_open())
{
inStream.close();
}
if(outStream.is_open())
{
outStream.flush();
outStream.close();
}
path.replace(path.find_last_of(name), name.size(), newName);
name = newName;
inStream.open(path);
outStream.open(path);
}
-24
View File
@@ -1,24 +0,0 @@
#pragma once
#include "Asset.h"
#include <fstream>
namespace Seele
{
class FileAsset
{
public:
FileAsset();
FileAsset(const std::string& directory, const std::string& name);
FileAsset(const std::string& fullPath);
virtual ~FileAsset();
std::ifstream& getReadStream();
std::ofstream& getWriteStream();
void rename(const std::string& newName);
private:
std::string name;
std::string path;
uint32 byteSize;
std::ifstream inStream;
std::ofstream outStream;
};
}
+22
View File
@@ -0,0 +1,22 @@
#include "MaterialLoader.h"
#include "Material/Material.h"
#include "Graphics/Graphics.h"
using namespace Seele;
MaterialLoader::MaterialLoader(Gfx::PGraphics graphics)
{
placeholderMaterial = new Material("shaders/Placeholder.semat");
placeholderMaterial->compile();
}
MaterialLoader::~MaterialLoader()
{
}
PMaterial MaterialLoader::queueAsset(const std::string& filePath)
{
PMaterial result = new Material(filePath);
//TODO
return result;
}
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include "MinimalEngine.h"
#include "Containers/List.h"
#include <thread>
#include <future>
namespace Seele
{
DECLARE_REF(Material)
DECLARE_NAME_REF(Gfx, Graphics);
class MaterialLoader
{
public:
MaterialLoader(Gfx::PGraphics graphic);
~MaterialLoader();
PMaterial queueAsset(const std::string& filePath);
private:
List<std::future<void>> futures;
PMaterial placeholderMaterial;
};
DEFINE_REF(MaterialLoader);
} // namespace Seele
+17
View File
@@ -0,0 +1,17 @@
#include "MeshAsset.h"
#include "Graphics/Mesh.h"
using namespace Seele;
MeshAsset::MeshAsset()
{
}
MeshAsset::MeshAsset(const std::string& directory, const std::string& name)
: Asset(directory, name)
{
}
MeshAsset::MeshAsset(const std::string& fullPath)
: Asset(fullPath)
{
}
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include "Asset.h"
namespace Seele
{
DECLARE_REF(Mesh);
class MeshAsset : public Asset
{
public:
MeshAsset();
MeshAsset(const std::string& directory, const std::string& name);
MeshAsset(const std::string& fullPath);
void setMesh(PMesh mesh)
{
std::scoped_lock lck(lock);
this->mesh = mesh;
}
private:
PMesh mesh;
};
DEFINE_REF(MeshAsset);
} // namespace Seele
+61
View File
@@ -0,0 +1,61 @@
#include "MeshLoader.h"
#include "Graphics/Graphics.h"
#include "MeshAsset.h"
#include "Graphics/Mesh.h"
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
using namespace Seele;
MeshLoader::MeshLoader(Gfx::PGraphics graphics)
: graphics(graphics)
{
}
MeshLoader::~MeshLoader()
{
}
void MeshLoader::importAsset(const std::string& path)
{
futures.add(std::async(std::launch::async, &MeshLoader::import, this, path));
}
void findMeshRoots(aiNode* node, List<aiNode*>& meshNodes)
{
if(node->mNumMeshes > 0)
{
meshNodes.add(node);
return;
}
for(uint32 i = 0; i < node->mNumChildren; ++i)
{
findMeshRoots(node->mChildren[i], meshNodes);
}
}
void MeshLoader::import(const std::string& path)
{
PMeshAsset asset = new MeshAsset(path);
asset->setStatus(Asset::Status::Loading);
Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(path.c_str(),
aiProcess_CalcTangentSpace |
aiProcess_FlipUVs |
aiProcess_ImproveCacheLocality |
aiProcess_OptimizeMeshes |
aiProcess_GenBoundingBoxes |
aiProcessPreset_TargetRealtime_Fast);
List<aiNode*> meshNodes;
findMeshRoots(scene->mRootNode, meshNodes);
for(auto meshNode : meshNodes)
{
std::cout << "Test:" << meshNode->mNumMeshes << std::endl;
}
PMesh mesh = new Mesh(nullptr, nullptr);
asset->setMesh(mesh);
asset->setStatus(Asset::Status::Ready);
}
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#include "MinimalEngine.h"
#include "Containers/List.h"
#include <thread>
#include <future>
namespace Seele
{
DECLARE_REF(MeshAsset)
DECLARE_NAME_REF(Gfx, Graphics);
class MeshLoader
{
public:
MeshLoader(Gfx::PGraphics graphic);
~MeshLoader();
void importAsset(const std::string& filePath);
private:
void import(const std::string& path);
List<std::future<void>> futures;
Gfx::PGraphics graphics;
};
DEFINE_REF(MeshLoader);
} // namespace Seele
+17
View File
@@ -0,0 +1,17 @@
#include "TextureAsset.h"
#include "Graphics/GraphicsResources.h"
using namespace Seele;
TextureAsset::TextureAsset()
{
}
TextureAsset::TextureAsset(const std::string& directory, const std::string& name)
: Asset(directory, name)
{
}
TextureAsset::TextureAsset(const std::string& fullPath)
: Asset(fullPath)
{
}
+25
View File
@@ -0,0 +1,25 @@
#include "Asset.h"
namespace Seele
{
DECLARE_NAME_REF(Gfx, Texture);
class TextureAsset : public Asset
{
public:
TextureAsset();
TextureAsset(const std::string& directory, const std::string& name);
TextureAsset(const std::string& fullPath);
void setTexture(Gfx::PTexture texture)
{
std::scoped_lock lck(lock);
this->texture = texture;
}
Gfx::PTexture getTexture()
{
return texture;
}
private:
Gfx::PTexture texture;
};
DEFINE_REF(TextureAsset);
} // namespace Seele
+61
View File
@@ -0,0 +1,61 @@
#include "TextureLoader.h"
#include "TextureAsset.h"
#include "Graphics/Graphics.h"
#include "AssetRegistry.h"
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
using namespace Seele;
TextureLoader::TextureLoader(Gfx::PGraphics graphics)
: graphics(graphics)
{
import("./textures/placeholder.png");
placeholderTexture = AssetRegistry::findTexture("./textures/placeholder.png");
}
TextureLoader::~TextureLoader()
{
}
void TextureLoader::importAsset(const std::string& filePath)
{
futures.add(std::async(std::launch::async, &TextureLoader::import, this, filePath));
}
void TextureLoader::import(const std::string& path)
{
PTextureAsset asset = new TextureAsset(path);
AssetRegistry::get().textures[path] = asset;
asset->setStatus(Asset::Status::Loading);
int x, y, n;
const std::string fullPath = std::string(asset->getFullPath());
unsigned char* data = stbi_load(fullPath.c_str(), &x, &y, &n, 0);
TextureCreateInfo createInfo;
createInfo.resourceData.data = data;
createInfo.resourceData.size = x * y * n * sizeof(unsigned char);
createInfo.width = x;
createInfo.height = y;
switch (n)
{
case 1:
createInfo.format = Gfx::SE_FORMAT_R8_UINT;
break;
case 2:
createInfo.format = Gfx::SE_FORMAT_R8G8_UINT;
break;
case 3:
createInfo.format = Gfx::SE_FORMAT_R8G8B8_UINT;
break;
case 4:
createInfo.format = Gfx::SE_FORMAT_R8G8B8A8_UINT;
break;
default:
break;
}
createInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
Gfx::PTexture2D texture = graphics->createTexture2D(createInfo);
texture->transferOwnership(Gfx::QueueType::GRAPHICS);
asset->setTexture(texture);
asset->setStatus(Asset::Status::Ready);
}
+24
View File
@@ -0,0 +1,24 @@
#pragma once
#include "MinimalEngine.h"
#include "Containers/List.h"
#include <thread>
#include <future>
namespace Seele
{
DECLARE_REF(TextureAsset);
DECLARE_NAME_REF(Gfx, Graphics);
class TextureLoader
{
public:
TextureLoader(Gfx::PGraphics graphic);
~TextureLoader();
void importAsset(const std::string& filePath);
private:
void import(const std::string& path);
Gfx::PGraphics graphics;
List<std::future<void>> futures;
PTextureAsset placeholderTexture;
};
DEFINE_REF(TextureLoader);
} // namespace Seele
+1 -1
View File
@@ -9,4 +9,4 @@ add_subdirectory(Containers/)
add_subdirectory(Graphics/)
add_subdirectory(Material/)
add_subdirectory(Math/)
add_subdirectory(Scene/)
add_subdirectory(Scene/)
+5
View File
@@ -385,6 +385,11 @@ public:
assert(index >= 0 && index < N);
return _data[index];
}
const T &operator[](int index) const
{
assert(index >= 0 && index < N);
return _data[index];
}
template <typename X>
class IteratorBase
+18
View File
@@ -132,6 +132,24 @@ public:
size++;
return insertedElement;
}
Iterator add(T&& value)
{
if (root == nullptr)
{
root = new Node();
tail = root;
}
tail->data = std::move(value);
Node *newTail = new Node();
newTail->prev = tail;
newTail->next = nullptr;
tail->next = newTail;
Iterator insertedElement(tail);
tail = newTail;
refreshIterators();
size++;
return insertedElement;
}
Iterator remove(Iterator pos)
{
size--;
+1
View File
@@ -141,6 +141,7 @@ public:
Node *node;
Array<Node *> traversal;
};
V &operator[](const K &key)
{
root = splay(root, key);
+2 -2
View File
@@ -1,7 +1,5 @@
target_sources(SeeleEngine
PRIVATE
ForwardPlusRenderPath.h
ForwardPlusRenderPath.cpp
GraphicsResources.h
GraphicsResources.cpp
GraphicsInitializer.h
@@ -10,6 +8,7 @@ target_sources(SeeleEngine
Graphics.cpp
Mesh.h
Mesh.cpp
MeshBatch.h
RenderCore.h
RenderCore.cpp
RenderPath.h
@@ -25,4 +24,5 @@ target_sources(SeeleEngine
WindowManager.h
WindowManager.cpp)
add_subdirectory(RenderPass/)
add_subdirectory(Vulkan/)
@@ -1,43 +0,0 @@
#include "ForwardPlusRenderPath.h"
#include "Scene/Scene.h"
#include "Material/MaterialInstance.h"
#include "Material/Material.h"
#include "GraphicsResources.h"
using namespace Seele;
Seele::ForwardPlusRenderPath::ForwardPlusRenderPath(Gfx::PGraphics graphics, Gfx::PViewport viewport)
: SceneRenderPath(graphics, viewport)
{
PMaterial material = new Material("D:\\Private\\Programming\\C++\\Seele\\test.mat");
material->compile();
}
Seele::ForwardPlusRenderPath::~ForwardPlusRenderPath()
{
}
void Seele::ForwardPlusRenderPath::beginFrame()
{
}
void Seele::ForwardPlusRenderPath::render()
{
for (auto entry : scene->getMeshBatches())
{
PMaterial material = entry.key;
Gfx::PRenderCommand renderCommand = graphics->createRenderCommand();
renderCommand->bindPipeline(material->getPipeline());
for (auto drawState : entry.value.instances)
{
renderCommand->bindVertexBuffer(drawState.vertexBuffer);
renderCommand->bindIndexBuffer(drawState.indexBuffer);
renderCommand->bindDescriptor(drawState.instance->getDescriptor());
renderCommand->draw(drawState);
}
}
}
void Seele::ForwardPlusRenderPath::endFrame()
{
}
@@ -1,17 +0,0 @@
#pragma once
#include "SceneRenderPath.h"
namespace Seele
{
class ForwardPlusRenderPath : public SceneRenderPath
{
public:
ForwardPlusRenderPath(Gfx::PGraphics graphics, Gfx::PViewport target);
virtual ~ForwardPlusRenderPath();
virtual void beginFrame() override;
virtual void render() override;
virtual void endFrame() override;
private:
};
} // namespace Seele
+16
View File
@@ -13,6 +13,12 @@ public:
Graphics();
virtual ~Graphics();
virtual void init(GraphicsInitializer initializer) = 0;
const QueueFamilyMapping getFamilyMapping() const
{
return queueMapping;
}
virtual PWindow createWindow(const WindowCreateInfo &createInfo) = 0;
virtual PViewport createViewport(PWindow owner, const ViewportCreateInfo &createInfo) = 0;
@@ -28,8 +34,18 @@ public:
virtual PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) = 0;
virtual PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) = 0;
virtual PRenderCommand createRenderCommand() = 0;
virtual PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) = 0;
virtual PControlShader createControlShader(const ShaderCreateInfo& createInfo) = 0;
virtual PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) = 0;
virtual PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) = 0;
virtual PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) = 0;
virtual PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) = 0;
virtual Gfx::PDescriptorLayout createDescriptorLayout() = 0;
virtual Gfx::PPipelineLayout createPipelineLayout() = 0;
protected:
QueueFamilyMapping queueMapping;
friend class Window;
};
DEFINE_REF(Graphics);
+46 -14
View File
@@ -1,3 +1,4 @@
#pragma once
#include "GraphicsEnums.h"
namespace Seele
@@ -42,8 +43,20 @@ struct ViewportCreateInfo
uint32 offsetX;
uint32 offsetY;
};
// doesnt own the data, only proxy it
struct BulkResourceData
{
uint32 size;
uint8 *data;
Gfx::QueueType owner;
BulkResourceData()
: size(0), data(nullptr), owner(Gfx::QueueType::GRAPHICS)
{
}
};
struct TextureCreateInfo
{
BulkResourceData resourceData;
uint32 width;
uint32 height;
uint32 depth;
@@ -53,20 +66,10 @@ struct TextureCreateInfo
uint32 samples;
Gfx::SeFormat format;
Gfx::SeImageUsageFlagBits usage;
Gfx::QueueType queueType;
TextureCreateInfo()
: width(1), height(1), depth(1), bArray(false), arrayLayers(1), mipLevels(1), samples(1), format(Gfx::SE_FORMAT_R32G32B32A32_SFLOAT), queueType(Gfx::QueueType::GRAPHICS), usage(Gfx::SE_IMAGE_USAGE_SAMPLED_BIT)
{
}
};
// doesnt own the data, only proxy it
struct BulkResourceData
{
uint32 size;
uint8 *data;
Gfx::QueueType owner;
BulkResourceData()
: size(0), data(nullptr), owner(Gfx::QueueType::GRAPHICS)
: resourceData(), width(1), height(1), depth(1), bArray(false), arrayLayers(1)
, mipLevels(1), samples(1), format(Gfx::SE_FORMAT_R32G32B32A32_SFLOAT)
, usage(Gfx::SE_IMAGE_USAGE_SAMPLED_BIT)
{
}
};
@@ -90,6 +93,15 @@ struct IndexBufferCreateInfo
{
}
};
struct ShaderCreateInfo
{
std::string code;
std::string entryPoint;
Array<const char*> typeParameter;
ShaderCreateInfo(const std::string& code)
: code(code)
{}
};
namespace Gfx
{
@@ -101,6 +113,10 @@ struct SePushConstantRange
};
struct VertexElement
{
VertexElement(){}
VertexElement(uint32 location, SeFormat vertexFormat, uint32 offset)
: location(location), vertexFormat(vertexFormat), offset(offset)
{}
uint32 location;
SeFormat vertexFormat;
uint32 offset;
@@ -173,7 +189,6 @@ struct GraphicsPipelineCreateInfo
Gfx::PEvaluationShader evalShader;
Gfx::PGeometryShader geometryShader;
Gfx::PFragmentShader fragmentShader;
Gfx::PPipelineLayout pipelineLayout;
Gfx::PRenderPass renderPass;
Gfx::SePrimitiveTopology topology;
Gfx::RasterizationState rasterizationState;
@@ -183,6 +198,23 @@ struct GraphicsPipelineCreateInfo
GraphicsPipelineCreateInfo()
{
std::memset(this, 0, sizeof(*this));
topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
rasterizationState.cullMode = Gfx::SE_CULL_MODE_BACK_BIT;
rasterizationState.polygonMode = Gfx::SE_POLYGON_MODE_FILL;
rasterizationState.frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE;
depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS;
depthStencilState.minDepthBounds = 0.0f;
depthStencilState.maxDepthBounds = 1.0f;
depthStencilState.stencilTestEnable = false;
depthStencilState.depthWriteEnable = true;
depthStencilState.depthTestEnable = true;
multisampleState.samples = 1;
colorBlend.attachmentCount = 0;
colorBlend.logicOpEnable = false;
colorBlend.blendConstants[0] = 1.0f;
colorBlend.blendConstants[1] = 1.0f;
colorBlend.blendConstants[2] = 1.0f;
colorBlend.blendConstants[3] = 1.0f;
}
};
} // namespace Seele
+72 -13
View File
@@ -1,5 +1,6 @@
#include "GraphicsResources.h"
#include "Material/MaterialInstance.h"
#include "Graphics.h"
using namespace Seele;
using namespace Seele::Gfx;
@@ -56,22 +57,60 @@ void PipelineLayout::addPushConstants(const SePushConstantRange &pushConstant)
pushConstants.add(pushConstant);
}
UniformBuffer::UniformBuffer()
QueueOwnedResource::QueueOwnedResource(PGraphics graphics, QueueType startQueueType)
: graphics(graphics)
, currentOwner(startQueueType)
{
}
QueueOwnedResource::~QueueOwnedResource()
{
}
void QueueOwnedResource::transferOwnership(QueueType newOwner)
{
if(graphics->getFamilyMapping().needsTransfer(currentOwner, newOwner))
{
executeOwnershipBarrier(newOwner);
currentOwner = newOwner;
}
}
Buffer::Buffer(PGraphics graphics, QueueType startQueue)
: QueueOwnedResource(graphics, startQueue)
{
}
Buffer::~Buffer()
{
}
UniformBuffer::UniformBuffer(PGraphics graphics, QueueType startQueueType)
: Buffer(graphics, startQueueType)
{
}
UniformBuffer::~UniformBuffer()
{
}
VertexBuffer::VertexBuffer(uint32 numVertices, uint32 vertexSize)
: numVertices(numVertices), vertexSize(vertexSize)
StructuredBuffer::StructuredBuffer(PGraphics graphics, QueueType startQueueType)
: Buffer(graphics, startQueueType)
{
}
StructuredBuffer::~StructuredBuffer()
{
}
VertexBuffer::VertexBuffer(PGraphics graphics, uint32 numVertices, uint32 vertexSize, QueueType startQueueType)
: Buffer(graphics, startQueueType)
, numVertices(numVertices), vertexSize(vertexSize)
{
}
VertexBuffer::~VertexBuffer()
{
}
IndexBuffer::IndexBuffer(uint32 size, Gfx::SeIndexType indexType)
: indexType(indexType)
IndexBuffer::IndexBuffer(PGraphics graphics, uint32 size, Gfx::SeIndexType indexType, QueueType startQueueType)
: Buffer(graphics, startQueueType)
, indexType(indexType)
{
switch (indexType)
{
@@ -87,9 +126,8 @@ IndexBuffer::IndexBuffer(uint32 size, Gfx::SeIndexType indexType)
IndexBuffer::~IndexBuffer()
{
}
VertexStream::VertexStream(PVertexBuffer buffer, uint8 instanced)
: buffer(buffer)
, instanced(instanced)
VertexStream::VertexStream(uint32 stride, uint8 instanced)
: stride(stride), instanced(instanced)
{
}
VertexStream::~VertexStream()
@@ -103,11 +141,6 @@ const Array<VertexElement> VertexStream::getVertexDescriptions() const
{
return vertexDescription;
}
Gfx::PVertexBuffer VertexStream::getVertexBuffer()
{
return buffer;
}
VertexDeclaration::VertexDeclaration()
{
}
@@ -125,6 +158,32 @@ const Array<VertexStream> &VertexDeclaration::getVertexStreams() const
return vertexStreams;
}
Texture::Texture(PGraphics graphics, Gfx::QueueType startQueueType)
: QueueOwnedResource(graphics, startQueueType)
{
}
Texture::~Texture()
{
}
Texture2D::Texture2D(PGraphics graphics, Gfx::QueueType startQueueType)
: Texture(graphics, startQueueType)
{
}
Texture2D::~Texture2D()
{
}
RenderCommand::RenderCommand()
{
}
RenderCommand::~RenderCommand()
{
}
RenderTargetLayout::RenderTargetLayout()
: inputAttachments(), colorAttachments(), depthAttachment()
{
+107 -52
View File
@@ -5,6 +5,7 @@
#include "Math/MemCRC.h"
#include "Material/MaterialInstance.h"
#include "GraphicsInitializer.h"
#include "MeshBatch.h"
#ifdef _DEBUG
#define ENABLE_VALIDATION
@@ -13,34 +14,10 @@
namespace Seele
{
DECLARE_NAME_REF(Gfx, VertexBuffer);
DECLARE_NAME_REF(Gfx, IndexBuffer);
struct DrawInstance
{
Matrix4 modelMatrix;
PMaterialInstance instance;
Gfx::PIndexBuffer indexBuffer;
Gfx::PVertexBuffer vertexBuffer;
uint32 numInstances;
uint32 baseVertexIndex;
uint32 minVertexIndex;
uint32 firstInstance;
DrawInstance()
: instance(nullptr), indexBuffer(nullptr), vertexBuffer(nullptr), modelMatrix(1), numInstances(1), baseVertexIndex(0), minVertexIndex(0), firstInstance(0)
{
}
};
struct DrawState
{
Array<DrawInstance> instances;
DrawState()
{
}
};
namespace Gfx
{
DECLARE_REF(Graphics);
class SamplerState
{
public:
@@ -182,6 +159,7 @@ public:
PipelineLayout() {}
virtual ~PipelineLayout() {}
virtual void create() = 0;
virtual void reset() = 0;
void addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout);
void addPushConstants(const SePushConstantRange &pushConstants);
virtual uint32 getHash() const = 0;
@@ -191,17 +169,79 @@ protected:
Array<SePushConstantRange> pushConstants;
};
DEFINE_REF(PipelineLayout);
class UniformBuffer
struct QueueFamilyMapping
{
uint32 graphicsFamily;
uint32 computeFamily;
uint32 transferFamily;
uint32 dedicatedTransferFamily;
uint32 getQueueTypeFamilyIndex(Gfx::QueueType type) const
{
switch (type)
{
case Gfx::QueueType::GRAPHICS:
return graphicsFamily;
case Gfx::QueueType::COMPUTE:
return computeFamily;
case Gfx::QueueType::TRANSFER:
return transferFamily;
case Gfx::QueueType::DEDICATED_TRANSFER:
return dedicatedTransferFamily;
default:
return 0x7fff;
}
}
bool needsTransfer(Gfx::QueueType src, Gfx::QueueType dst) const
{
uint32 srcIndex = getQueueTypeFamilyIndex(src);
uint32 dstIndex = getQueueTypeFamilyIndex(dst);
return srcIndex != dstIndex;
}
};
class QueueOwnedResource
{
public:
UniformBuffer();
QueueOwnedResource(PGraphics graphics, QueueType startQueueType);
virtual ~QueueOwnedResource();
//Preliminary checks to see if the barrier should be executed at all
void transferOwnership(QueueType newOwner);
protected:
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
Gfx::QueueType currentOwner;
PGraphics graphics;
};
DEFINE_REF(QueueOwnedResource);
class Buffer : public QueueOwnedResource
{
public:
Buffer(PGraphics graphics, QueueType startQueueType);
virtual ~Buffer();
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
};
class UniformBuffer : public Buffer
{
public:
UniformBuffer(PGraphics graphics, QueueType startQueueType);
virtual ~UniformBuffer();
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
};
DEFINE_REF(UniformBuffer);
class VertexBuffer
class VertexBuffer : public Buffer
{
public:
VertexBuffer(uint32 numVertices, uint32 vertexSize);
VertexBuffer(PGraphics graphics, uint32 numVertices, uint32 vertexSize, QueueType startQueueType);
virtual ~VertexBuffer();
inline uint32 getNumVertices()
{
@@ -214,14 +254,17 @@ public:
}
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
uint32 numVertices;
uint32 vertexSize;
};
DEFINE_REF(VertexBuffer);
class IndexBuffer
class IndexBuffer : public Buffer
{
public:
IndexBuffer(uint32 size, Gfx::SeIndexType index);
IndexBuffer(PGraphics graphics, uint32 size, Gfx::SeIndexType index, QueueType startQueueType);
virtual ~IndexBuffer();
inline uint32 getNumIndices() const
{
@@ -233,34 +276,41 @@ public:
}
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
Gfx::SeIndexType indexType;
uint32 numIndices;
};
DEFINE_REF(IndexBuffer);
class StructuredBuffer
class StructuredBuffer : public Buffer
{
public:
virtual ~StructuredBuffer()
{
}
StructuredBuffer(PGraphics graphics, QueueType startQueueType);
virtual ~StructuredBuffer();
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
};
DEFINE_REF(StructuredBuffer);
class VertexStream
{
public:
VertexStream() {}
VertexStream(PVertexBuffer buffer, uint8 instanced);
VertexStream(uint32 stride, uint8 instanced);
~VertexStream();
void addVertexElement(VertexElement element);
const Array<VertexElement> getVertexDescriptions() const;
PVertexBuffer getVertexBuffer();
inline uint8 isInstanced() const { return instanced; }
private:
PVertexBuffer buffer;
uint32 stride;
uint32 offset;
Array<VertexElement> vertexDescription;
uint8 instanced;
PVertexBuffer vertexBuffer;
};
DEFINE_REF(VertexStream);
class VertexDeclaration
{
public:
@@ -276,41 +326,46 @@ DEFINE_REF(VertexDeclaration);
class GraphicsPipeline
{
public:
GraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) : createInfo(createInfo) {}
GraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo, PPipelineLayout layout) : createInfo(createInfo) , layout(layout) {}
virtual ~GraphicsPipeline(){}
const GraphicsPipelineCreateInfo& getCreateInfo() const {return createInfo;}
PPipelineLayout getPipelineLayout() const { return layout; }
protected:
PPipelineLayout layout;
GraphicsPipelineCreateInfo createInfo;
};
DEFINE_REF(GraphicsPipeline);
class Texture
class Texture : public QueueOwnedResource
{
public:
virtual ~Texture()
{
}
Texture(PGraphics graphics, QueueType startQueueType);
virtual ~Texture();
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
};
DEFINE_REF(Texture);
class Texture2D : public Texture
{
public:
virtual ~Texture2D()
{
}
Texture2D(PGraphics graphics, QueueType startQueueType);
virtual ~Texture2D();
protected:
//Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
};
DEFINE_REF(Texture2D);
class RenderCommand
{
public:
virtual ~RenderCommand()
{
}
RenderCommand();
virtual ~RenderCommand();
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) = 0;
virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0;
virtual void bindVertexBuffer(Gfx::PVertexBuffer vertexBuffer) = 0;
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0;
virtual void draw(DrawInstance data) = 0;
virtual void draw(const MeshBatchElement& data) = 0;
};
DEFINE_REF(RenderCommand);
+12
View File
@@ -1 +1,13 @@
#include "Mesh.h"
using namespace Seele;
Mesh::Mesh(Gfx::PVertexBuffer vertexBuffer, Gfx::PIndexBuffer indexBuffer)
: vertexBuffer(vertexBuffer)
, indexBuffer(indexBuffer)
{
}
Mesh::~Mesh()
{
}
+3 -2
View File
@@ -10,7 +10,8 @@ public:
~Mesh();
private:
Gfx::VertexBuffer vertexBuffer;
Gfx::IndexBuffer indexBuffer;
Gfx::PVertexBuffer vertexBuffer;
Gfx::PIndexBuffer indexBuffer;
};
DEFINE_REF(Mesh);
} // namespace Seele
+97
View File
@@ -0,0 +1,97 @@
#pragma once
namespace Seele
{
DECLARE_NAME_REF(Gfx, VertexBuffer);
DECLARE_NAME_REF(Gfx, IndexBuffer);
DECLARE_NAME_REF(Gfx, UniformBuffer);
DECLARE_REF(Material);
DECLARE_REF(VertexFactory);
struct MeshBatchElement
{
public:
Gfx::PUniformBuffer uniformBuffer;
Gfx::PIndexBuffer indexBuffer;
union
{
uint32* instanceRuns;
};
uint32 firstIndex;
uint32 numPrimitives;
uint32 numInstances;
uint32 baseVertexIndex;
uint32 minVertexIndex;
uint32 maxVertexIndex;
uint8 isInstanced : 1;
Gfx::PVertexBuffer indirectArgsBuffer;
MeshBatchElement()
: uniformBuffer(nullptr)
, indexBuffer(nullptr)
, indirectArgsBuffer(nullptr)
, firstIndex(0)
, numPrimitives(0)
, numInstances(1)
, baseVertexIndex(0)
, minVertexIndex(0)
, maxVertexIndex(0)
{}
};
struct MeshBatch
{
Array<MeshBatchElement> elements;
uint8 useReverseCulling : 1;
uint8 isBackfaceCullingDisabled : 1;
uint8 isCastingShadow : 1;
uint8 useWireframe : 1;
const Gfx::SePrimitiveTopology topology;
const PVertexFactory vertexFactory;
const PMaterial material;
inline int32 getNumPrimitives() const
{
int32 count = 0;
for(uint32 index = 0; index < elements.size(); ++index)
{
if(elements[index].isInstanced && elements[index].instanceRuns)
{
for(uint32 run = 0; run < elements[index].numInstances; ++run)
{
count += elements[index].numPrimitives * (elements[index].instanceRuns[run * 2 + 1] - elements[index].instanceRuns[run * 2] - 1);
}
}
else
{
count += elements[index].numPrimitives * elements[index].numInstances;
}
}
return count;
}
MeshBatch()
: useReverseCulling(false)
, isBackfaceCullingDisabled(false)
, isCastingShadow(true)
, useWireframe(false)
, vertexFactory(nullptr)
, material(nullptr)
, topology(Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
{
elements.add();
}
};
DECLARE_REF(PrimitiveComponent);
struct StaticMeshBatch : public MeshBatch
{
uint32 index;
PPrimitiveComponent primitiveComponent;
};
} // namespace Seele
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include "MinimalEngine.h"
namespace Seele
{
class BasePass
{
public:
BasePass();
~BasePass();
private:
};
} // namespace Seele
@@ -0,0 +1,10 @@
target_sources(SeeleEngine
PRIVATE
BasePass.h
BasePass.cpp
DepthPrepass.h
DepthPrepass.cpp
MeshProcessor.h
MeshProcessor.cpp
VertexFactory.h
VertexFactory.cpp)
@@ -0,0 +1,54 @@
#include "MeshProcessor.h"
#include "Graphics/Graphics.h"
#include "VertexFactory.h"
using namespace Seele;
MeshProcessor::MeshProcessor(const PScene scene, Gfx::PGraphics graphics)
: scene(scene)
, graphics(graphics)
{
}
MeshProcessor::~MeshProcessor()
{
}
void MeshProcessor::buildMeshDrawCommands(
const MeshBatch& meshBatch,
const PPrimitiveComponent primitiveComponent,
PMaterial material,
Gfx::PVertexShader vertexShader,
Gfx::PControlShader controlShader,
Gfx::PEvaluationShader evaluationShader,
Gfx::PGeometryShader geometryShader,
Gfx::PFragmentShader fragmentShader,
bool positionOnly)
{
const PVertexFactory vertexFactory = meshBatch.vertexFactory;
GraphicsPipelineCreateInfo pipelineInitializer;
pipelineInitializer.topology = meshBatch.topology;
Gfx::PVertexDeclaration vertexDecl = positionOnly ? vertexFactory->getPositionDeclaration() : vertexFactory->getDeclaration();
pipelineInitializer.vertexDeclaration = vertexDecl;
pipelineInitializer.vertexShader = vertexShader;
pipelineInitializer.controlShader = controlShader;
pipelineInitializer.evalShader = evaluationShader;
pipelineInitializer.geometryShader = geometryShader;
pipelineInitializer.fragmentShader = fragmentShader;
VertexInputStreamArray vertexStreams;
if(positionOnly)
{
vertexFactory->getPositionOnlyStream(vertexStreams);
}
else
{
vertexFactory->getStreams(vertexStreams);
}
if(vertexShader != nullptr)
{
}
}
@@ -0,0 +1,32 @@
#pragma once
#include "MinimalEngine.h"
#include "Scene/Scene.h"
#include "Graphics/GraphicsResources.h"
#include "Graphics/MeshBatch.h"
namespace Seele
{
class MeshProcessor
{
public:
MeshProcessor(const PScene scene, Gfx::PGraphics graphics);
virtual ~MeshProcessor();
private:
PScene scene;
Gfx::PGraphics graphics;
virtual void addMeshBatch(
const MeshBatch& meshBatch,
const PPrimitiveComponent primitiveComponent,
int32 staticMeshId = -1) = 0;
void buildMeshDrawCommands(
const MeshBatch& meshBatch,
const PPrimitiveComponent primitiveComponent,
PMaterial material,
Gfx::PVertexShader vertexShader,
Gfx::PControlShader controlShader,
Gfx::PEvaluationShader evaluationShader,
Gfx::PGeometryShader geometryShader,
Gfx::PFragmentShader fragmentShader,
bool positionOnly);
};
} // namespace Seele
@@ -0,0 +1,28 @@
#include "VertexFactory.h"
using namespace Seele;
void VertexFactory::getStreams(VertexInputStreamArray& outVertexStreams) const
{
for(uint32 i = 0; i < streams.size(); ++i)
{
const Gfx::VertexStream& stream = streams[i];
if(stream.vertexBuffer == nullptr)
{
outVertexStreams.add(VertexInputStream(i, 0, nullptr));
}
else
{
outVertexStreams.add(VertexInputStream(i, stream.offset, stream.vertexBuffer));
}
}
}
void VertexFactory::getPositionOnlyStream(VertexInputStreamArray& outVertexStreams) const
{
for (uint32 i = 0; i < positionStream.size(); ++i)
{
const Gfx::VertexStream& stream = positionStream[i];
outVertexStreams.add(VertexInputStream(i, stream.offset, stream.vertexBuffer));
}
}
@@ -0,0 +1,92 @@
#pragma once
#include "MinimalEngine.h"
#include "Graphics/GraphicsResources.h"
namespace Seele
{
struct VertexInputStream
{
uint32 streamIndex : 4;
uint32 offset : 28;
Gfx::PVertexBuffer vertexBuffer;
VertexInputStream()
: streamIndex(0), offset(0), vertexBuffer(nullptr)
{
}
VertexInputStream(uint32 streamIndex, uint32 offset, Gfx::PVertexBuffer vertexBuffer)
: streamIndex(streamIndex), offset(offset), vertexBuffer(vertexBuffer)
{
assert(this->streamIndex == streamIndex && this->offset == offset);
}
inline bool operator==(const VertexInputStream &rhs) const
{
if (streamIndex != rhs.streamIndex || offset != rhs.offset || vertexBuffer != rhs.vertexBuffer)
{
return false;
}
return true;
}
inline bool operator!=(const VertexInputStream &rhs) const
{
return !(*this == rhs);
}
};
struct VertexStreamComponent
{
const Gfx::PVertexBuffer vertexBuffer = nullptr;
uint32 streamOffset = 0;
uint8 offset = 0;
uint8 stride;
Gfx::SeFormat type;
VertexStreamComponent()
{
}
VertexStreamComponent(const Gfx::PVertexBuffer vertexBuffer, uint32 offset, uint32 stride, Gfx::SeFormat type)
: vertexBuffer(vertexBuffer)
, streamOffset(0)
, offset(offset)
, stride(stride)
, type(type)
{
}
VertexStreamComponent(const Gfx::PVertexBuffer vertexBuffer, uint32 streamOffset, uint32 offset, uint32 stride, Gfx::SeFormat type)
: vertexBuffer(vertexBuffer)
, streamOffset(streamOffset)
, offset(offset)
, stride(stride)
, type(type)
{
}
};
typedef Array<VertexInputStream> VertexInputStreamArray;
class VertexFactory
{
public:
VertexFactory()
{
}
void getStreams(VertexInputStreamArray& outVertexStreams) const;
void getPositionOnlyStream(VertexInputStreamArray& outVertexStreams) const;
virtual bool supportsTesselation() { return false; }
Gfx::PVertexDeclaration getDeclaration() const {return declaration;}
Gfx::PVertexDeclaration getPositionDeclaration() const {return positionDeclaration;}
private:
StaticArray<Gfx::VertexStream, 16> streams;
StaticArray<Gfx::VertexStream, 16> positionStream;
Gfx::PVertexDeclaration declaration;
Gfx::PVertexDeclaration positionDeclaration;
};
DEFINE_REF(VertexFactory);
} // namespace Seele
+1
View File
@@ -9,6 +9,7 @@ public:
RenderPath(Gfx::PGraphics graphics, Gfx::PViewport target);
virtual ~RenderPath();
virtual void applyArea(URect area);
virtual void init() = 0;
virtual void beginFrame() = 0;
virtual void render() = 0;
virtual void endFrame() = 0;
+30 -3
View File
@@ -1,12 +1,39 @@
#include "SceneRenderPath.h"
#include "Scene/Scene.h"
#include "Material/Material.h"
Seele::SceneRenderPath::SceneRenderPath(Gfx::PGraphics graphics, Gfx::PViewport target)
using namespace Seele;
SceneRenderPath::SceneRenderPath(Gfx::PGraphics graphics, Gfx::PViewport target)
: RenderPath(graphics, target)
{
scene = new Scene();
}
Seele::SceneRenderPath::~SceneRenderPath()
SceneRenderPath::~SceneRenderPath()
{
}
void SceneRenderPath::setTargetScene(PScene newScene)
{
scene = newScene;
}
void SceneRenderPath::init()
{
}
void SceneRenderPath::beginFrame()
{
}
void SceneRenderPath::render()
{
}
void SceneRenderPath::endFrame()
{
}
+5 -3
View File
@@ -9,9 +9,11 @@ class SceneRenderPath : public RenderPath
public:
SceneRenderPath(Gfx::PGraphics graphics, Gfx::PViewport target);
virtual ~SceneRenderPath();
virtual void beginFrame() = 0;
virtual void render() = 0;
virtual void endFrame() = 0;
void setTargetScene(PScene scene);
virtual void init();
virtual void beginFrame();
virtual void render();
virtual void endFrame();
protected:
PScene scene;
+2 -2
View File
@@ -1,11 +1,11 @@
#include "SceneView.h"
#include "ForwardPlusRenderPath.h"
#include "SceneRenderPath.h"
#include "Window.h"
Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo)
: View(graphics, owner, createInfo)
{
renderer = new ForwardPlusRenderPath(graphics, viewport);
renderer = new SceneRenderPath(graphics, viewport);
}
Seele::SceneView::~SceneView()
+28 -8
View File
@@ -61,16 +61,15 @@ Allocation::Allocation(PGraphics graphics, Allocator *allocator, VkDeviceSize si
Allocation::~Allocation()
{
allocator->free(this);
}
PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDeviceSize alignment)
{
std::scoped_lock lck(lock);
if (isDedicated)
{
if (activeAllocations.empty())
if (activeAllocations.empty() && requestedSize == bytesAllocated)
{
assert(requestedSize == bytesAllocated);
PSubAllocation suballoc = freeRanges[0];
activeAllocations[0] = suballoc.getHandle();
freeRanges.clear();
@@ -82,9 +81,9 @@ PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice
return nullptr;
}
}
for (uint32 i = 0; i < freeRanges.size(); ++i)
for (auto it : freeRanges)
{
PSubAllocation freeAllocation = freeRanges[i];
PSubAllocation freeAllocation = it.value;
VkDeviceSize allocatedOffset = freeAllocation->allocatedOffset;
VkDeviceSize alignedOffset = align(allocatedOffset, alignment);
VkDeviceSize alignmentAdjustment = alignedOffset - allocatedOffset;
@@ -115,32 +114,48 @@ PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice
void Allocation::markFree(SubAllocation *allocation)
{
// Dont free if it is already a free allocation, since they also mark themselves on deletion
if(freeRanges.find(allocation->allocatedOffset) != nullptr)
{
return;
}
VkDeviceSize lowerBound = allocation->allocatedOffset;
VkDeviceSize upperBound = allocation->allocatedOffset + allocation->allocatedSize;
PSubAllocation allocHandle;
std::scoped_lock lck(lock);
//Join lower bound
for (auto freeRange : freeRanges)
{
PSubAllocation freeAlloc = freeRange.value;
if (freeAlloc->allocatedOffset + freeAlloc->allocatedSize + 1 == lowerBound)
if (freeAlloc->allocatedOffset + freeAlloc->allocatedSize == lowerBound)
{
//extend freeAlloc by the allocatedSize
freeAlloc->allocatedSize += allocation->allocatedSize;
allocHandle = freeAlloc;
break;
}
}
auto foundAlloc = freeRanges.find(upperBound + 1);
//Join upper bound
auto foundAlloc = freeRanges.find(upperBound);
if (foundAlloc != freeRanges.end())
{
if (allocHandle == nullptr)
// There is a free allocation ending where the new free one ends
if (allocHandle != nullptr)
{
// extend allocHandle by another foundAlloc->allocatedSize bytes
allocHandle->allocatedSize += foundAlloc->value->allocatedSize;
freeRanges.erase(foundAlloc->key);
}
else
{
// set foundAlloc back by size amount
allocHandle = foundAlloc->value;
// remove from offset map since key changes
freeRanges.erase(foundAlloc->key);
allocHandle->allocatedOffset -= allocation->allocatedSize;
allocHandle->alignedOffset -= allocation->allocatedSize;
// place back at correct offset
freeRanges[allocHandle->allocatedOffset] = allocHandle;
}
}
if (allocHandle == nullptr)
@@ -150,6 +165,8 @@ void Allocation::markFree(SubAllocation *allocation)
}
activeAllocations.erase(allocation->allocatedOffset);
bytesUsed -= allocation->allocatedSize;
// TODO: delete allocation when bytesUsed == 0
}
Allocator::Allocator(PGraphics graphics)
@@ -167,6 +184,7 @@ Allocator::Allocator(PGraphics graphics)
Allocator::~Allocator()
{
std::scoped_lock lck(lock);
for (auto heap : heaps)
{
for (auto alloc : heap.allocations)
@@ -181,6 +199,7 @@ Allocator::~Allocator()
PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo)
{
std::scoped_lock lck(lock);
const VkMemoryRequirements &requirements = memRequirements2.memoryRequirements;
uint8 memoryTypeIndex;
VK_CHECK(findMemoryType(requirements.memoryTypeBits, properties, &memoryTypeIndex));
@@ -213,6 +232,7 @@ PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2
void Allocator::free(Allocation *allocation)
{
std::scoped_lock lck(lock);
for (auto heap : heaps)
{
for (uint32 i = 0; i < heap.allocations.size(); ++i)
@@ -3,6 +3,7 @@
#include "VulkanGraphicsEnums.h"
#include "Containers/Map.h"
#include "Containers/Array.h"
#include <mutex>
namespace Seele
{
@@ -101,6 +102,7 @@ private:
VkMemoryPropertyFlags properties;
Map<VkDeviceSize, SubAllocation *> activeAllocations;
Map<VkDeviceSize, PSubAllocation> freeRanges;
std::mutex lock;
void *mappedPointer;
uint8 memoryTypeIndex;
uint8 isDedicated : 1;
@@ -153,6 +155,7 @@ private:
};
Array<HeapInfo> heaps;
VkResult findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties, uint8 *typeIndex);
std::mutex lock;
PGraphics graphics;
VkPhysicalDeviceMemoryProperties memProperties;
};
+60 -17
View File
@@ -17,7 +17,7 @@ struct PendingBuffer
static Map<Buffer *, PendingBuffer> pendingBuffers;
Buffer::Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType)
: QueueOwnedResource(graphics, queueType), currentBuffer(0), size(size)
: graphics(graphics), currentBuffer(0), size(size), currentOwner(queueType)
{
if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ||
usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT ||
@@ -58,7 +58,7 @@ Buffer::Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::Q
Buffer::~Buffer()
{
auto fence = getCommands()->getCommands()->getFence();
auto fence = graphics->getQueueCommands(currentOwner)->getCommands()->getFence();
auto &deletionQueue = graphics->getDeletionQueue();
VkDevice device = graphics->getDevice();
VkBuffer buf[Gfx::numFramesBuffered];
@@ -74,11 +74,11 @@ void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
VkBufferMemoryBarrier barrier =
init::BufferMemoryBarrier();
PCommandBufferManager sourceManager = getCommands();
PCommandBufferManager sourceManager = graphics->getQueueCommands(currentOwner);
PCommandBufferManager dstManager = nullptr;
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
QueueFamilyMapping mapping = graphics->getFamilyMapping();
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
barrier.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(currentOwner);
barrier.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner);
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
@@ -134,7 +134,7 @@ void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
vkCmdPipelineBarrier(srcCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
vkCmdPipelineBarrier(dstCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
sourceManager->submitCommands();
cachedCmdBufferManager = dstManager;
currentOwner = newOwner;
}
void *Buffer::lock(bool bWriteOnly)
@@ -160,19 +160,19 @@ void *Buffer::lock(bool bWriteOnly)
pending.prevQueue = currentOwner;
if (bWriteOnly)
{
transferOwnership(Gfx::QueueType::DEDICATED_TRANSFER);
requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
data = stagingBuffer->getMappedPointer();
pending.stagingBuffer = stagingBuffer;
}
else
{
PCmdBuffer current = getCommands()->getCommands();
getCommands()->submitCommands();
getCommands()->waitForCommands(current);
PCmdBuffer current = graphics->getQueueCommands(currentOwner)->getCommands();
graphics->getQueueCommands(currentOwner)->submitCommands();
graphics->getQueueCommands(currentOwner)->waitForCommands(current);
transferOwnership(Gfx::QueueType::DEDICATED_TRANSFER);
VkCommandBuffer handle = getCommands()->getCommands()->getHandle();
requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
VkCommandBuffer handle = graphics->getQueueCommands(currentOwner)->getCommands()->getHandle();
VkBufferMemoryBarrier barrier =
init::BufferMemoryBarrier();
@@ -194,8 +194,8 @@ void *Buffer::lock(bool bWriteOnly)
vkCmdCopyBuffer(handle, buffers[currentBuffer].buffer, stagingBuffer->getHandle(), 1, &regions);
getCommands()->submitCommands();
vkQueueWaitIdle(getCommands()->getQueue()->getHandle());
graphics->getQueueCommands(currentOwner)->submitCommands();
vkQueueWaitIdle(graphics->getQueueCommands(currentOwner)->getQueue()->getHandle());
stagingBuffer->flushMappedMemory();
pending.stagingBuffer = stagingBuffer;
@@ -219,7 +219,7 @@ void Buffer::unlock()
if (pending.bWriteOnly)
{
PStagingBuffer stagingBuffer = pending.stagingBuffer;
PCmdBuffer cmdBuffer = getCommands()->getCommands();
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
VkBufferCopy region;
@@ -227,13 +227,14 @@ void Buffer::unlock()
region.size = size;
vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, &region);
}
transferOwnership(pending.prevQueue);
requestOwnershipTransfer(pending.prevQueue);
graphics->getStagingManager()->releaseStagingBuffer(pending.stagingBuffer);
}
}
UniformBuffer::UniformBuffer(PGraphics graphics, const BulkResourceData &resourceData)
: Buffer(graphics, resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, resourceData.owner)
, Gfx::UniformBuffer(graphics, resourceData.owner)
{
if (resourceData.data != nullptr)
{
@@ -247,6 +248,17 @@ UniformBuffer::~UniformBuffer()
{
}
void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
{
Gfx::QueueOwnedResource::transferOwnership(newOwner);
Buffer::currentOwner = newOwner;
}
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
Buffer::executeOwnershipBarrier(newOwner);
}
VkAccessFlags UniformBuffer::getSourceAccessMask()
{
return VK_ACCESS_MEMORY_WRITE_BIT;
@@ -259,6 +271,7 @@ VkAccessFlags UniformBuffer::getDestAccessMask()
StructuredBuffer::StructuredBuffer(PGraphics graphics, const BulkResourceData &resourceData)
: Buffer(graphics, resourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, resourceData.owner)
, Gfx::StructuredBuffer(graphics, resourceData.owner)
{
if (resourceData.data != nullptr)
{
@@ -272,6 +285,16 @@ StructuredBuffer::~StructuredBuffer()
{
}
void StructuredBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
{
Gfx::QueueOwnedResource::transferOwnership(newOwner);
}
void StructuredBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
Buffer::executeOwnershipBarrier(newOwner);
}
VkAccessFlags StructuredBuffer::getSourceAccessMask()
{
return VK_ACCESS_MEMORY_WRITE_BIT;
@@ -284,7 +307,7 @@ VkAccessFlags StructuredBuffer::getDestAccessMask()
VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData)
: Buffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, resourceData.resourceData.owner)
, Gfx::VertexBuffer(resourceData.numVertices, resourceData.vertexSize)
, Gfx::VertexBuffer(graphics, resourceData.numVertices, resourceData.vertexSize, resourceData.resourceData.owner)
{
if (resourceData.resourceData.data != nullptr)
{
@@ -298,6 +321,16 @@ VertexBuffer::~VertexBuffer()
{
}
void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
{
Gfx::QueueOwnedResource::transferOwnership(newOwner);
}
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
Buffer::executeOwnershipBarrier(newOwner);
}
VkAccessFlags VertexBuffer::getSourceAccessMask()
{
return VK_ACCESS_MEMORY_WRITE_BIT;
@@ -310,7 +343,7 @@ VkAccessFlags VertexBuffer::getDestAccessMask()
IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData)
: Buffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, resourceData.resourceData.owner)
, Gfx::IndexBuffer(resourceData.resourceData.size, resourceData.indexType)
, Gfx::IndexBuffer(graphics, resourceData.resourceData.size, resourceData.indexType, resourceData.resourceData.owner)
{
if (resourceData.resourceData.data != nullptr)
{
@@ -324,6 +357,16 @@ IndexBuffer::~IndexBuffer()
{
}
void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
{
Gfx::QueueOwnedResource::transferOwnership(newOwner);
}
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
Buffer::executeOwnershipBarrier(newOwner);
}
VkAccessFlags IndexBuffer::getSourceAccessMask()
{
return VK_ACCESS_MEMORY_WRITE_BIT;
@@ -7,6 +7,7 @@
#include "VulkanRenderPass.h"
#include "VulkanPipeline.h"
#include "VulkanDescriptorSets.h"
#include "Graphics/MeshBatch.h"
using namespace Seele;
using namespace Seele::Vulkan;
@@ -174,9 +175,9 @@ void SecondaryCmdBuffer::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer)
PIndexBuffer buf = indexBuffer.cast<IndexBuffer>();
vkCmdBindIndexBuffer(handle, buf->getHandle(), 0, VK_INDEX_TYPE_UINT16);
}
void SecondaryCmdBuffer::draw(DrawInstance data)
void SecondaryCmdBuffer::draw(const MeshBatchElement& data)
{
vkCmdDrawIndexed(handle, data.indexBuffer->getNumIndices(), data.numInstances, data.minVertexIndex, data.baseVertexIndex, data.firstInstance);
vkCmdDrawIndexed(handle, data.indexBuffer->getNumIndices(), data.numInstances, data.minVertexIndex, data.baseVertexIndex, 0);
}
CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
@@ -77,7 +77,7 @@ public:
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet) override;
virtual void bindVertexBuffer(Gfx::PVertexBuffer vertexBuffer) override;
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
virtual void draw(DrawInstance data) override;
virtual void draw(const MeshBatchElement& data) override;
private:
PGraphicsPipeline pipeline;
@@ -72,6 +72,13 @@ void PipelineLayout::create()
layoutHash = memCrc32(&createInfo, sizeof(VkPipelineLayoutCreateInfo), 0);
}
void PipelineLayout::reset()
{
vkDestroyPipelineLayout(graphics->getDevice(), layoutHandle, nullptr);
descriptorSetLayouts.clear();
pushConstants.clear();
}
DescriptorSet::~DescriptorSet()
{
}
@@ -34,6 +34,7 @@ public:
}
virtual ~PipelineLayout();
virtual void create();
virtual void reset();
inline VkPipelineLayout getHandle() const
{
return layoutHandle;
+60 -3
View File
@@ -7,6 +7,8 @@
#include "VulkanRenderPass.h"
#include "VulkanFramebuffer.h"
#include "VulkanPipelineCache.h"
#include "VulkanDescriptorSets.h"
#include "VulkanShader.h"
#include "Graphics/GraphicsResources.h"
#include <glfw/glfw3.h>
@@ -99,9 +101,7 @@ void Graphics::executeCommands(Array<Gfx::PRenderCommand> commands)
Gfx::PTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo)
{
PTexture2D result = new Texture2D(this, createInfo.width, createInfo.height, createInfo.bArray,
createInfo.bArray, createInfo.arrayLayers, createInfo.format,
createInfo.samples, createInfo.usage, createInfo.queueType);
PTexture2D result = new Texture2D(this, createInfo);
return result;
}
@@ -133,11 +133,51 @@ Gfx::PRenderCommand Graphics::createRenderCommand()
cmdBuffer->begin(getGraphicsCommands()->getCommands());
return cmdBuffer;
}
Gfx::PVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createInfo)
{
PVertexShader shader = new VertexShader(this);
shader->create(createInfo);
return shader;
}
Gfx::PControlShader Graphics::createControlShader(const ShaderCreateInfo& createInfo)
{
PControlShader shader = new ControlShader(this);
shader->create(createInfo);
return shader;
}
Gfx::PEvaluationShader Graphics::createEvaluationShader(const ShaderCreateInfo& createInfo)
{
PEvaluationShader shader = new EvaluationShader(this);
shader->create(createInfo);
return shader;
}
Gfx::PGeometryShader Graphics::createGeometryShader(const ShaderCreateInfo& createInfo)
{
PGeometryShader shader = new GeometryShader(this);
shader->create(createInfo);
return shader;
}
Gfx::PFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo)
{
PFragmentShader shader = new FragmentShader(this);
shader->create(createInfo);
return shader;
}
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo)
{
PGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo);
return pipeline;
}
Gfx::PDescriptorLayout Graphics::createDescriptorLayout()
{
PDescriptorLayout layout = new DescriptorLayout(this);
return layout;
}
Gfx::PPipelineLayout Graphics::createPipelineLayout()
{
PPipelineLayout layout = new PipelineLayout(this);
return layout;
}
VkInstance Graphics::getInstance() const
{
@@ -154,6 +194,23 @@ VkPhysicalDevice Graphics::getPhysicalDevice() const
return physicalDevice;
}
PCommandBufferManager Graphics::getQueueCommands(Gfx::QueueType queueType)
{
switch (queueType)
{
case Gfx::QueueType::GRAPHICS:
return graphicsCommands;
case Gfx::QueueType::COMPUTE:
return computeCommands;
case Gfx::QueueType::TRANSFER:
return transferCommands;
case Gfx::QueueType::DEDICATED_TRANSFER:
return dedicatedTransferCommands;
default:
throw new std::logic_error("invalid queue type");
}
}
PCommandBufferManager Graphics::getGraphicsCommands()
{
return graphicsCommands;
+9 -5
View File
@@ -22,15 +22,12 @@ public:
VkDevice getDevice() const;
VkPhysicalDevice getPhysicalDevice() const;
PCommandBufferManager getQueueCommands(Gfx::QueueType queueType);
PCommandBufferManager getGraphicsCommands();
PCommandBufferManager getComputeCommands();
PCommandBufferManager getTransferCommands();
PCommandBufferManager getDedicatedTransferCommands();
const QueueFamilyMapping getFamilyMapping() const
{
return queueMapping;
}
QueueOwnedResourceDeletion &getDeletionQueue()
{
return deletionQueue;
@@ -56,8 +53,16 @@ public:
virtual Gfx::PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) override;
virtual Gfx::PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) override;
virtual Gfx::PRenderCommand createRenderCommand() override;
virtual Gfx::PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PControlShader createControlShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) override;
virtual Gfx::PDescriptorLayout createDescriptorLayout() override;
virtual Gfx::PPipelineLayout createPipelineLayout() override;
protected:
Array<const char *> getRequiredExtensions();
void initInstance(GraphicsInitializer initInfo);
@@ -73,7 +78,6 @@ protected:
PQueue computeQueue;
PQueue transferQueue;
PQueue dedicatedTransferQueue;
QueueFamilyMapping queueMapping;
QueueOwnedResourceDeletion deletionQueue;
PPipelineCache pipelineCache;
PCommandBufferManager graphicsCommands;
@@ -50,47 +50,6 @@ void QueueOwnedResourceDeletion::run()
}
}
QueueOwnedResource::QueueOwnedResource(PGraphics graphics, Gfx::QueueType startQueueType)
: graphics(graphics), currentOwner(startQueueType)
{
}
QueueOwnedResource::~QueueOwnedResource()
{
cachedCmdBufferManager = nullptr;
graphics = nullptr;
}
void QueueOwnedResource::transferOwnership(Gfx::QueueType newOwner)
{
if (graphics->getFamilyMapping().needsTransfer(currentOwner, newOwner))
{
executeOwnershipBarrier(newOwner);
currentOwner = newOwner;
}
}
PCommandBufferManager QueueOwnedResource::getCommands()
{
if (cachedCmdBufferManager != nullptr)
{
assert(cachedCmdBufferManager->getQueue()->getFamilyIndex() == graphics->getFamilyMapping().getQueueTypeFamilyIndex(currentOwner));
return cachedCmdBufferManager;
}
switch (currentOwner)
{
case Gfx::QueueType::GRAPHICS:
return graphics->getGraphicsCommands();
case Gfx::QueueType::COMPUTE:
return graphics->getComputeCommands();
case Gfx::QueueType::TRANSFER:
return graphics->getTransferCommands();
case Gfx::QueueType::DEDICATED_TRANSFER:
return graphics->getDedicatedTransferCommands();
}
return nullptr;
}
Semaphore::Semaphore(PGraphics graphics)
: graphics(graphics)
{
@@ -1,8 +1,5 @@
#pragma once
#include "Graphics/GraphicsResources.h"
#include <thread>
#include <functional>
#include <condition_variable>
#include <vulkan/vulkan.h>
namespace Seele
@@ -54,35 +51,6 @@ private:
};
DEFINE_REF(Fence);
struct QueueFamilyMapping
{
uint32 graphicsFamily;
uint32 computeFamily;
uint32 transferFamily;
uint32 dedicatedTransferFamily;
uint32 getQueueTypeFamilyIndex(Gfx::QueueType type) const
{
switch (type)
{
case Gfx::QueueType::GRAPHICS:
return graphicsFamily;
case Gfx::QueueType::COMPUTE:
return computeFamily;
case Gfx::QueueType::TRANSFER:
return transferFamily;
case Gfx::QueueType::DEDICATED_TRANSFER:
return dedicatedTransferFamily;
default:
return VK_QUEUE_FAMILY_IGNORED;
}
}
bool needsTransfer(Gfx::QueueType src, Gfx::QueueType dst) const
{
uint32 srcIndex = getQueueTypeFamilyIndex(src);
uint32 dstIndex = getQueueTypeFamilyIndex(dst);
return srcIndex != dstIndex;
}
};
class QueueOwnedResourceDeletion
{
public:
@@ -103,24 +71,8 @@ private:
static std::condition_variable cv;
static List<PendingItem> deletionQueue;
};
class QueueOwnedResource
{
public:
QueueOwnedResource(PGraphics graphics, Gfx::QueueType startQueueType);
virtual ~QueueOwnedResource();
PCommandBufferManager getCommands();
//Preliminary checks to see if the barrier should be executed at all
void transferOwnership(Gfx::QueueType newOwner);
protected:
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) = 0;
Gfx::QueueType currentOwner;
PGraphics graphics;
PCommandBufferManager cachedCmdBufferManager;
};
DEFINE_REF(QueueOwnedResource);
class Buffer : public QueueOwnedResource
class Buffer
{
public:
Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType);
@@ -146,11 +98,14 @@ protected:
uint32 numBuffers;
uint32 currentBuffer;
uint32 size;
PGraphics graphics;
Gfx::QueueType currentOwner;
void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0;
virtual VkAccessFlags getSourceAccessMask() = 0;
virtual VkAccessFlags getDestAccessMask() = 0;
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
};
DEFINE_REF(Buffer);
@@ -161,8 +116,12 @@ public:
virtual ~UniformBuffer();
protected:
// Inherited via Vulkan::Buffer
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
};
DEFINE_REF(UniformBuffer);
@@ -173,8 +132,12 @@ public:
virtual ~StructuredBuffer();
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
};
DEFINE_REF(StructuredBuffer);
@@ -185,8 +148,12 @@ public:
virtual ~VertexBuffer();
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
};
DEFINE_REF(VertexBuffer);
@@ -197,17 +164,20 @@ public:
virtual ~IndexBuffer();
protected:
// Inherited via Vulkan::Buffer
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
};
DEFINE_REF(IndexBuffer);
class TextureHandle : public QueueOwnedResource
class TextureHandle
{
public:
TextureHandle(PGraphics graphics, VkImageViewType viewType, uint32 sizeX, uint32 sizeY, uint32 sizeZ,
bool bArray, uint32 arraySize, uint32 mipLevels, Gfx::SeFormat format,
uint32 samples, Gfx::SeImageUsageFlags usage, Gfx::QueueType owner = Gfx::QueueType::GRAPHICS, VkImage existingImage = VK_NULL_HANDLE);
TextureHandle(PGraphics graphics, VkImageViewType viewType,
const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
virtual ~TextureHandle();
inline VkImageView getView() const
@@ -234,9 +204,10 @@ public:
{
return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
}
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
void executeOwnershipBarrier(Gfx::QueueType newOwner);
void changeLayout(VkImageLayout newLayout);
Gfx::QueueType currentOwner;
private:
PGraphics graphics;
PSubAllocation allocation;
@@ -276,10 +247,7 @@ DEFINE_REF(TextureBase);
class Texture2D : public TextureBase, public Gfx::Texture2D
{
public:
Texture2D(PGraphics graphics, uint32 sizeX, uint32 sizeY,
bool bArray, uint32 arraySize, uint32 mipLevels, Gfx::SeFormat format,
uint32 samples, Gfx::SeImageUsageFlags usage,
Gfx::QueueType owner = Gfx::QueueType::GRAPHICS, VkImage existingImage = VK_NULL_HANDLE);
Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
virtual ~Texture2D();
inline uint32 getSizeX() const
{
@@ -305,8 +273,10 @@ public:
{
return textureHandle->isDepthStencil();
}
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
private:
};
DEFINE_REF(Texture2D);
@@ -6,9 +6,8 @@ using namespace Seele;
using namespace Seele::Vulkan;
GraphicsPipeline::GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const GraphicsPipelineCreateInfo& createInfo)
: Gfx::GraphicsPipeline(createInfo)
: Gfx::GraphicsPipeline(createInfo, pipelineLayout)
, graphics(graphics)
, layout(pipelineLayout)
, pipeline(handle)
{
}
@@ -24,5 +23,5 @@ void GraphicsPipeline::bind(VkCommandBuffer handle)
VkPipelineLayout GraphicsPipeline::getLayout() const
{
return layout->getHandle();
return layout.cast<PipelineLayout>()->getHandle();
}
@@ -16,7 +16,6 @@ public:
VkPipelineLayout getLayout() const;
private:
VkPipeline pipeline;
PPipelineLayout layout;
PGraphics graphics;
};
DEFINE_REF(GraphicsPipeline);
@@ -52,6 +52,9 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
createInfo.pNext = 0;
createInfo.flags = 0;
createInfo.stageCount = 0;
PPipelineLayout layout = graphics->createPipelineLayout();
VkPipelineTessellationStateCreateInfo tessInfo;
VkPipelineShaderStageCreateInfo stageInfos[5];
std::memset(stageInfos, 0, sizeof(stageInfos));
@@ -63,6 +66,10 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
vertInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
vertInfo.module = shader->getModuleHandle();
vertInfo.pName = shader->getEntryPointName();
for(auto descriptor : shader->getDescriptorLayouts())
{
layout->addDescriptorLayout(descriptor.key, descriptor.value);
}
}
if(gfxInfo.controlShader != nullptr)
{
@@ -86,6 +93,15 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
tessInfo.pNext = 0;
tessInfo.flags = 0;
tessInfo.patchControlPoints = control->getNumPatches();
for(auto descriptor : eval->getDescriptorLayouts())
{
layout->addDescriptorLayout(descriptor.key, descriptor.value);
}
for(auto descriptor : control->getDescriptorLayouts())
{
layout->addDescriptorLayout(descriptor.key, descriptor.value);
}
}
if(gfxInfo.geometryShader != nullptr)
{
@@ -96,6 +112,11 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
geometryInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT;
geometryInfo.module = geometry->getModuleHandle();
geometryInfo.pName = geometry->getEntryPointName();
for(auto descriptor : geometry->getDescriptorLayouts())
{
layout->addDescriptorLayout(descriptor.key, descriptor.value);
}
}
if(gfxInfo.fragmentShader != nullptr)
{
@@ -106,7 +127,13 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
fragmentInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
fragmentInfo.module = fragment->getModuleHandle();
fragmentInfo.pName = fragment->getEntryPointName();
for(auto descriptor : fragment->getDescriptorLayouts())
{
layout->addDescriptorLayout(descriptor.key, descriptor.value);
}
}
layout->create();
VkPipelineVertexInputStateCreateInfo vertexInput =
init::PipelineVertexInputStateCreateInfo();
Gfx::PVertexDeclaration vertexDecl = gfxInfo.vertexDeclaration;
@@ -116,7 +143,7 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
uint32 bindingNum = 0;
for(auto vertexBinding : vertexStreams)
{
uint32 stride = vertexBinding.getVertexBuffer()->getVertexSize();
uint32 stride = 0;
for(auto vertexAttrib : vertexBinding.getVertexDescriptions())
{
auto attrib = attribDesc.add();
@@ -137,9 +164,9 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
VkPipelineInputAssemblyStateCreateInfo assemblyInfo =
init::PipelineInputAssemblyStateCreateInfo(
cast(gfxInfo.topology),
0,
false
cast(gfxInfo.topology),
0,
false
);
VkPipelineViewportStateCreateInfo viewportInfo =
@@ -214,6 +241,7 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
0
);
createInfo.pStages = stageInfos;
createInfo.pVertexInputState = &vertexInput;
createInfo.pInputAssemblyState = &assemblyInfo;
@@ -225,7 +253,7 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
createInfo.pColorBlendState = &blendState;
createInfo.pDynamicState = &dynamicState;
createInfo.renderPass = gfxInfo.renderPass.cast<RenderPass>()->getHandle();
createInfo.layout = gfxInfo.pipelineLayout.cast<PipelineLayout>()->getHandle();
createInfo.layout = layout->getHandle();
createInfo.subpass = 0;
VkPipeline pipelineHandle;
@@ -235,6 +263,6 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
int64 delta = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - beginTime).count();
std::cout << "Gfx creation time: " << delta << std::endl;
PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, gfxInfo.pipelineLayout.cast<PipelineLayout>(), gfxInfo);
PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout, gfxInfo);
return result;
}
+99 -1
View File
@@ -1,4 +1,102 @@
#include "VulkanShader.h"
#include "VulkanGraphics.h"
#include "VulkanDescriptorSets.h"
#include "slang.h"
using namespace slang;
using namespace Seele;
using namespace Seele::Vulkan;
using namespace Seele::Vulkan;
Shader::Shader(PGraphics graphics, ShaderType shaderType, VkShaderStageFlags stage)
: graphics(graphics)
, type(shaderType)
, stage(stage)
{
}
Shader::~Shader()
{
if(module != VK_NULL_HANDLE)
{
vkDestroyShaderModule(graphics->getDevice(), module, nullptr);
}
}
Map<uint32, PDescriptorLayout> Shader::getDescriptorLayouts()
{
return descriptorSets;
}
static SlangStage getStageFromShaderType(ShaderType type)
{
switch (type)
{
case ShaderType::VERTEX:
return SLANG_STAGE_VERTEX;
case ShaderType::CONTROL:
return SLANG_STAGE_HULL;
case ShaderType::EVALUATION:
return SLANG_STAGE_DOMAIN;
case ShaderType::GEOMETRY:
return SLANG_STAGE_GEOMETRY;
case ShaderType::FRAGMENT:
return SLANG_STAGE_PIXEL;
default:
return SLANG_STAGE_NONE;
}
}
void Shader::create(const ShaderCreateInfo& createInfo)
{
entryPointName = createInfo.entryPoint;
static SlangSession* session = spCreateSession(NULL);
SlangCompileRequest* request = spCreateCompileRequest(session);
int targetIndex = spAddCodeGenTarget(request, SLANG_SPIRV);
spSetTargetProfile(request, targetIndex, spFindProfile(session, "glsl_vk"));
spSetDumpIntermediates(request, true);
int translationUnitIndex = spAddTranslationUnit(request, SLANG_SOURCE_LANGUAGE_SLANG, "");
spAddTranslationUnitSourceString(
request,
translationUnitIndex,
entryPointName.c_str(),
createInfo.code.c_str()
);
spAddSearchPath(request, "shaders/lib/");
spSetGlobalGenericArgs(request, createInfo.typeParameter.size(), createInfo.typeParameter.data());
int entryPointIndex = spAddEntryPoint(request, translationUnitIndex, entryPointName.c_str(), getStageFromShaderType(type));
if(spCompile(request))
{
char const* diagnostice = spGetDiagnosticOutput(request);
std::cout << diagnostice << std::endl;
}
ShaderReflection* reflection = slang::ShaderReflection::get(request);
uint32 parameterCount = reflection->getParameterCount();
for(uint32 i = 0; i < parameterCount; ++i)
{
VariableLayoutReflection* parameter =
reflection->getParameterByIndex(i);
uint32 descriptorIndex = parameter->getBindingSpace();
uint32 descriptorBinding = parameter->getBindingIndex();
PDescriptorLayout& layout = descriptorSets[descriptorIndex];
std::cout << parameter->getTypeLayout()->getName() << std::endl;
//layout->addDescriptorBinding(descriptorBinding, parame)
}
size_t dataSize = 0;
const void* data = spGetEntryPointCode(request, entryPointIndex, &dataSize);
VkShaderModuleCreateInfo moduleInfo;
moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
moduleInfo.pNext = nullptr;
moduleInfo.flags = 0;
moduleInfo.codeSize = dataSize;
moduleInfo.pCode = static_cast<const uint32*>(data);
VK_CHECK(vkCreateShaderModule(graphics->getDevice(), &moduleInfo, nullptr, &module));
}
+11 -3
View File
@@ -6,13 +6,16 @@ namespace Seele
{
namespace Vulkan
{
DECLARE_REF(Graphics);
DECLARE_REF(DescriptorLayout);
class Shader
{
public:
Shader(PGraphics graphics, ShaderType shaderType, VkShaderStageFlags stage);
virtual ~Shader();
void create(const ShaderCreateInfo& createInfo);
VkShaderModule getModuleHandle() const
{
return module;
@@ -21,18 +24,23 @@ public:
{
return entryPointName.c_str();
}
Map<uint32, PDescriptorLayout> getDescriptorLayouts();
private:
PGraphics graphics;
Map<uint32, PDescriptorLayout> descriptorSets;
VkShaderModule module;
VkShaderStageFlags stage;
ShaderType type;
std::string entryPointName;
};
DEFINE_REF(Shader);
template <typename Base, ShaderType shaderType, VkShaderStageFlags stage>
template <typename Base, ShaderType shaderType, VkShaderStageFlags stageFlags>
class ShaderBase : public Base, public Shader
{
public:
ShaderBase(PGraphics graphics)
: Shader(graphics, shaderType, stage)
: Shader(graphics, shaderType, stageFlags)
{
}
virtual ~ShaderBase()
+82 -26
View File
@@ -29,10 +29,21 @@ VkImageAspectFlags getAspectFromFormat(Gfx::SeFormat format)
}
}
TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, uint32 sizeX, uint32 sizeY, uint32 sizeZ,
bool bArray, uint32 arraySize, uint32 mipLevel,
Gfx::SeFormat format, uint32 samples, Gfx::SeImageUsageFlags usage, Gfx::QueueType owner, VkImage existingImage)
: QueueOwnedResource(graphics, owner), graphics(graphics), sizeX(sizeX), sizeY(sizeY), sizeZ(sizeZ), mipLevels(mipLevel), format(format), samples(samples), usage(usage), arrayCount(bArray ? arraySize : 1), aspect(getAspectFromFormat(format)), image(existingImage), layout(VK_IMAGE_LAYOUT_UNDEFINED)
TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
const TextureCreateInfo& createInfo, VkImage existingImage)
: currentOwner(createInfo.resourceData.owner)
, graphics(graphics)
, sizeX(createInfo.width)
, sizeY(createInfo.height)
, sizeZ(createInfo.depth)
, mipLevels(createInfo.mipLevels)
, format(createInfo.format)
, samples(createInfo.samples)
, usage(createInfo.usage)
, arrayCount(createInfo.bArray ? createInfo.arrayLayers : 1)
, aspect(getAspectFromFormat(createInfo.format))
, image(existingImage)
, layout(VK_IMAGE_LAYOUT_UNDEFINED)
{
if (existingImage == VK_NULL_HANDLE)
{
@@ -42,7 +53,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, uint3
info.extent.width = sizeX;
info.extent.height = sizeY;
info.extent.depth = sizeZ;
info.arrayLayers = arraySize;
info.arrayLayers = arrayCount;
info.format = cast(format);
uint32 layerCount = 1;
@@ -67,13 +78,18 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, uint3
default:
break;
}
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
info.mipLevels = mipLevel;
info.initialLayout = layout;
info.mipLevels = mipLevels;
info.arrayLayers = arrayCount * layerCount;
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
info.samples = (VkSampleCountFlagBits)samples;
info.tiling = VK_IMAGE_TILING_OPTIMAL;
info.usage = usage;
//To upload to the image we need to specify transfer dst
if(createInfo.resourceData.size > 0)
{
info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
}
VK_CHECK(vkCreateImage(graphics->getDevice(), &info, nullptr, &image));
VkMemoryDedicatedRequirements memDedicatedRequirements;
@@ -91,6 +107,37 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, uint3
allocation = allocator->allocate(requirements, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, image);
vkBindImageMemory(graphics->getDevice(), image, allocation->getHandle(), allocation->getOffset());
}
const BulkResourceData& resourceData = createInfo.resourceData;
if(resourceData.size > 0)
{
changeLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
PStagingBuffer staging = graphics->getStagingManager()->allocateStagingBuffer(resourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
void* data = staging->getMappedPointer();
std::memcpy(data, resourceData.data, resourceData.size);
staging->flushMappedMemory();
PCommandBufferManager cmdBufferManager = graphics->getQueueCommands(currentOwner);
VkBufferImageCopy region;
region.bufferOffset = 0;
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageOffset = {0, 0, 0};
region.imageExtent = {sizeX, sizeX, sizeZ};
vkCmdCopyBufferToImage(cmdBufferManager->getCommands()->getHandle(),
staging->getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
// When loading a texture from a file, we will almost always use it as a texture map for fragment shaders
changeLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
}
VkImageViewCreateInfo viewInfo =
init::ImageViewCreateInfo();
viewInfo.subresourceRange = init::ImageSubresourceRange(aspect);
@@ -106,7 +153,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, uint3
TextureHandle::~TextureHandle()
{
auto &deletionQueue = graphics->getDeletionQueue();
auto fence = getCommands()->getCommands()->getFence();
auto fence = graphics->getQueueCommands(currentOwner)->getCommands()->getFence();
VkDevice device = graphics->getDevice();
VkImageView view = defaultView;
VkImage img = image;
@@ -114,6 +161,20 @@ TextureHandle::~TextureHandle()
deletionQueue.addPendingDelete(fence, [device, img]() { vkDestroyImage(device, img, nullptr); });
}
void TextureHandle::changeLayout(VkImageLayout newLayout)
{
VkImageMemoryBarrier barrier =
init::ImageMemoryBarrier(
image,
layout,
newLayout);
PCommandBufferManager cmdManager = graphics->getQueueCommands(currentOwner);
vkCmdPipelineBarrier(cmdManager->getCommands()->getHandle(),
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
0, 0, nullptr, 0, nullptr, 1, &barrier);
layout = newLayout;
}
void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
VkImageMemoryBarrier imageBarrier =
@@ -122,11 +183,11 @@ void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner)
imageBarrier.oldLayout = layout;
imageBarrier.newLayout = layout;
imageBarrier.subresourceRange = init::ImageSubresourceRange(aspect);
PCommandBufferManager sourceManager = getCommands();
PCommandBufferManager sourceManager = graphics->getQueueCommands(currentOwner);
PCommandBufferManager dstManager = nullptr;
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
QueueFamilyMapping mapping = graphics->getFamilyMapping();
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
imageBarrier.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(currentOwner);
imageBarrier.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner);
if (currentOwner == Gfx::QueueType::TRANSFER || currentOwner == Gfx::QueueType::DEDICATED_TRANSFER)
@@ -150,7 +211,7 @@ void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner)
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstManager = graphics->getTransferCommands();
}
else if (currentOwner == Gfx::QueueType::DEDICATED_TRANSFER)
else if (newOwner == Gfx::QueueType::DEDICATED_TRANSFER)
{
imageBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
@@ -173,30 +234,25 @@ void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner)
vkCmdPipelineBarrier(sourceCmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
vkCmdPipelineBarrier(destCmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
sourceManager->submitCommands();
cachedCmdBufferManager = dstManager;
}
void TextureBase::changeLayout(VkImageLayout newLayout)
{
VkImageMemoryBarrier barrier =
init::ImageMemoryBarrier(
textureHandle->image,
textureHandle->layout,
newLayout);
vkCmdPipelineBarrier(textureHandle->getCommands()->getCommands()->getHandle(),
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
0, 0, nullptr, 0, nullptr, 1, &barrier);
textureHandle->layout = newLayout;
textureHandle->changeLayout(newLayout);
}
Texture2D::Texture2D(PGraphics graphics, uint32 sizeX, uint32 sizeY,
bool bArray, uint32 arraySize, uint32 mipLevels, Gfx::SeFormat format,
uint32 samples, Gfx::SeImageUsageFlags usage, Gfx::QueueType owner, VkImage existingImage)
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
: Gfx::Texture2D(graphics, createInfo.resourceData.owner)
{
textureHandle = new TextureHandle(graphics, bArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
sizeX, sizeY, 1, bArray, arraySize, mipLevels, format, samples, usage, owner, existingImage);
textureHandle = new TextureHandle(graphics, createInfo.bArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
createInfo, existingImage);
}
Texture2D::~Texture2D()
{
}
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
textureHandle->executeOwnershipBarrier(newOwner);
}
@@ -181,13 +181,17 @@ void Window::createSwapchain()
PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands();
TextureCreateInfo backBufferCreateInfo;
backBufferCreateInfo.width = sizeX;
backBufferCreateInfo.height = sizeY;
backBufferCreateInfo.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
backBufferCreateInfo.resourceData.owner = Gfx::QueueType::GRAPHICS;
backBufferCreateInfo.format = cast(surfaceFormat.format);
for (uint32 i = 0; i < numSwapchainImages; ++i)
{
imageAcquired[i] = new Semaphore(graphics);
renderFinished[i] = new Semaphore(graphics);
backBufferImages[i] = new Texture2D(graphics, sizeX, sizeY, false, 1, 1,
cast(surfaceFormat.format), 1, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
Gfx::QueueType::GRAPHICS, swapchainImages[i]);
backBufferImages[i] = new Texture2D(graphics, backBufferCreateInfo, swapchainImages[i]);
VkClearColorValue clearColor;
std::memset(&clearColor, 0, sizeof(VkClearColorValue));
+2
View File
@@ -1,6 +1,8 @@
#include "WindowManager.h"
#include "Vulkan/VulkanGraphics.h"
Gfx::PGraphics WindowManager::graphics;
Seele::WindowManager::WindowManager()
{
graphics = new Vulkan::Graphics();
+2 -2
View File
@@ -14,7 +14,7 @@ public:
PWindow addWindow(const WindowCreateInfo &createInfo);
void beginFrame();
void endFrame();
Gfx::PGraphics getGraphics()
static Gfx::PGraphics getGraphics()
{
return graphics;
}
@@ -25,7 +25,7 @@ public:
private:
Array<PWindow> windows;
Gfx::PGraphics graphics;
static Gfx::PGraphics graphics;
};
DEFINE_REF(WindowManager);
} // namespace Seele
+4 -1
View File
@@ -2,5 +2,8 @@ target_sources(SeeleEngine
PRIVATE
Material.h
Material.cpp
MaterialAsset.h
MaterialAsset.cpp
MaterialInstance.h
MaterialInstance.cpp)
MaterialInstance.cpp
ShaderExpression.h)
+66 -9
View File
@@ -1,5 +1,7 @@
#include "Material.h"
#include "Asset/AssetRegistry.h"
#include <nlohmann/json.hpp>
#include <sstream>
using namespace Seele;
using json = nlohmann::json;
@@ -9,29 +11,84 @@ Material::Material()
}
Material::Material(const std::string& directory, const std::string& name)
: FileAsset(directory, name)
: MaterialAsset(directory, name)
{
}
Material::Material(const std::string& fullPath)
: FileAsset(fullPath)
{
: MaterialAsset(fullPath)
{
}
Material::~Material()
{
}
void Material::compile()
{
auto& stream = getReadStream();
stream.seekg(0);
json j;
stream >> j;
std::cout << j["test"] << std::endl;
}
std::stringstream codeStream;
materialName = j["name"].get<std::string>();
std::string profile = j["profile"].get<std::string>();
codeStream << "import LightEnv;" << std::endl;
codeStream << "import Material;" << std::endl;
codeStream << "import BRDF;" << std::endl;
codeStream << "import InputGeometry;" << std::endl;
Gfx::PGraphicsPipeline Material::getPipeline()
{
return pipeline;
codeStream << "struct " << materialName << ": IMaterial {" << std::endl;
for(auto param : j["params"].items())
{
std::string type = param.value()["type"].get<std::string>();
auto default = param.value().find("default");
if(type.compare("float") == 0)
{
PFloatParameter p = new FloatParameter();
if(default != param.value().end())
{
p->defaultValue = std::stof(default.value().get<std::string>());
}
parameters.add(p);
}
else if(type.compare("float3") == 0)
{
PVectorParameter p = new VectorParameter();
if(default != param.value().end())
{
p->defaultValue = parseVector(default.value().get<std::string>().c_str());
}
parameters.add(p);
}
else if(type.compare("Texture2D") == 0)
{
PTextureParameter p = new TextureParameter();
if(default != param.value().end())
{
}
parameters.add(p);
}
else if(type.compare("SamplerState") == 0)
{
PSamplerParameter p = new SamplerParameter();
parameters.add(p);
}
else
{
std::cout << "Error unsupported parameter type" << std::endl;
}
codeStream << type << " " << param.key();
}
codeStream << "typedef " << profile << " BRDF;" << std::endl;
codeStream << profile << " prepare(MaterialPixelParameter geometry){" << std::endl;
codeStream << profile << " result;" << std::endl;
for(auto c : j["code"].items())
{
codeStream << c.value().get<std::string>() << std::endl;
}
codeStream << "}};" << std::endl;
}
+7 -29
View File
@@ -1,44 +1,22 @@
#pragma once
#include "MinimalEngine.h"
#include "Asset/FileAsset.h"
#include "Graphics/GraphicsResources.h"
#include <nlohmann/json_fwd.hpp>
#include "MaterialAsset.h"
namespace Seele
{
struct FloatExpression
{
float data;
std::string name;
uint32 location;
};
struct VectorExpression
{
Vector data;
std::string name;
uint32 location;
};
struct TextureExpression
{
Gfx::PTexture texture;
std::string name;
uint32 location;
};
DECLARE_NAME_REF(Gfx, GraphicsPipeline);
DECLARE_NAME_REF(Gfx, PipelineLayout);
class Material : public FileAsset
class Material : public MaterialAsset
{
public:
Material();
Material(const std::string &directory, const std::string &name);
Material(const std::string &fullPath);
~Material();
void compile();
Gfx::PGraphicsPipeline getPipeline();
inline std::string getMaterialName() const {return materialName;}
private:
Gfx::PGraphicsPipeline pipeline;
Gfx::PPipelineLayout pipelineLayout;
void compile();
std::string materialName;
friend class MaterialLoader;
};
DEFINE_REF(Material);
} // namespace Seele
+21
View File
@@ -0,0 +1,21 @@
#include "MaterialAsset.h"
using namespace Seele;
MaterialAsset::MaterialAsset()
{
}
MaterialAsset::MaterialAsset(const std::string& directory, const std::string& name)
: Asset(directory, name)
{
}
MaterialAsset::MaterialAsset(const std::string& fullPath)
: Asset(fullPath)
{
}
MaterialAsset::~MaterialAsset()
{
}
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include "Asset/Asset.h"
#include "ShaderExpression.h"
namespace Seele
{
class MaterialAsset : public Asset
{
public:
MaterialAsset();
MaterialAsset(const std::string &directory, const std::string &name);
MaterialAsset(const std::string &fullPath);
~MaterialAsset();
protected:
//For now its simply the collection of parameters, since there is no point for expressions
Array<PShaderParameter> parameters;
};
DEFINE_REF(MaterialAsset);
} // namespace Seele
+2 -2
View File
@@ -8,12 +8,12 @@ MaterialInstance::MaterialInstance()
}
MaterialInstance::MaterialInstance(const std::string& directory, const std::string& name)
: FileAsset(directory, name)
: Asset(directory, name)
{
}
MaterialInstance::MaterialInstance(const std::string& fullPath)
: FileAsset(fullPath)
: Asset(fullPath)
{
}
+2 -2
View File
@@ -1,11 +1,11 @@
#pragma once
#include "Asset/FileAsset.h"
#include "Asset/Asset.h"
namespace Seele
{
DECLARE_NAME_REF(Gfx, DescriptorSet);
DECLARE_REF(Material);
class MaterialInstance : public FileAsset
class MaterialInstance : public Asset
{
public:
MaterialInstance();
+79
View File
@@ -0,0 +1,79 @@
#pragma once
#include "MinimalEngine.h"
namespace Seele
{
struct ExpressionInput
{
};
struct ExpressionOutput
{
};
struct ShaderExpression
{
};
struct ShaderParameter : public ShaderExpression
{
std::string name;
};
DEFINE_REF(ShaderParameter);
struct FloatParameter : public ShaderParameter
{
float defaultValue;
bool setParameter(const std::string& paramName, float newDefault)
{
if(name.compare(paramName) == 0)
{
defaultValue = newDefault;
return true;
}
return false;
}
};
DEFINE_REF(FloatParameter);
struct VectorParameter : public ShaderParameter
{
Vector defaultValue;
bool setParameter(const std::string& paramName, Vector newDefault)
{
if(name.compare(paramName) == 0)
{
defaultValue = newDefault;
return true;
}
return false;
}
};
DEFINE_REF(VectorParameter);
DECLARE_NAME_REF(Gfx, Texture2D);
struct TextureParameter : public ShaderParameter
{
Gfx::PTexture2D defaultValue;
bool setParameter(const std::string& paramName, Gfx::PTexture2D newDefault)
{
if(name.compare(paramName) == 0)
{
return true;
}
return false;
}
};
DEFINE_REF(TextureParameter);
DECLARE_NAME_REF(Gfx, SamplerState);
struct SamplerParameter : public ShaderParameter
{
Gfx::PSamplerState defaultValue;
bool setParameter(const std::string& paramName, Gfx::PSamplerState newDefault)
{
if(name.compare(paramName) == 0)
{
return true;
}
return false;
}
};
DEFINE_REF(SamplerParameter);
} // namespace Seele
+1
View File
@@ -3,5 +3,6 @@ target_sources(SeeleEngine
Math.h
Matrix.h
Vector.h
Vector.cpp
Transform.h
Transform.cpp)
+1
View File
@@ -1,3 +1,4 @@
#pragma once
#include "Vector.h"
#include "Matrix.h"
#include "EngineTypes.h"
+3 -2
View File
@@ -181,9 +181,10 @@ Transform &Transform::operator=(Transform &&other)
return *this;
}
Transform &Transform::operator*(const Transform &other) const
Transform &Transform::operator*(const Transform &other)
{
Transform outTransform;
multiply(&outTransform, this, &other);
return outTransform;
*this = std::move(outTransform);
return *this;
}
+1 -1
View File
@@ -28,7 +28,7 @@ public:
Transform &operator=(const Transform &other);
Transform &operator=(Transform &&other);
Transform &operator*(const Transform &other) const;
Transform &operator*(const Transform &other);
private:
Vector4 position;
+17
View File
@@ -0,0 +1,17 @@
#include "Vector.h"
#include <regex>
using namespace Seele;
Vector Seele::parseVector(const char* str)
{
//regex pattern consisting of 'float3(xComp, yComp, zComp)', more also matches for invalid floats, but that will throw later
std::regex pattern("float3\\(\\s*([0-9.]+f?)\\s*,\\s*([0-9.]+f?)\\s*,\\s*([0-9.]+f?)\\s*\\)");
std::cmatch base_match;
std::regex_match(str, base_match, pattern);
//match 0 is the whole expression
float x = std::stof(base_match[1].str());
float y = std::stof(base_match[2].str());
float z = std::stof(base_match[3].str());
return Vector(x, y, z);
}
+2
View File
@@ -22,6 +22,8 @@ typedef glm::ivec4 IVector4;
typedef glm::quat Quaternion;
Vector parseVector(const char*);
static inline float square(float x)
{
return x * x;
+21 -15
View File
@@ -1,9 +1,4 @@
#pragma once
#include <assert.h>
#include <memory>
#include <atomic>
#include <cstring>
#include <iostream>
#include "Containers/Map.h"
#include "EngineTypes.h"
#include "Math/Math.h"
@@ -52,7 +47,10 @@ public:
~RefObject()
{
registeredObjects.erase(handle);
// we cant always have the definition of every class
#pragma warning(disable : 4150)
delete handle;
#pragma warning(default : 4150)
}
RefObject &operator=(const RefObject &rhs)
{
@@ -74,15 +72,15 @@ public:
}
return *this;
}
bool operator==(const RefObject &other) const
inline bool operator==(const RefObject &other) const
{
return handle == other.handle;
}
bool operator!=(const RefObject &other) const
inline bool operator!=(const RefObject &other) const
{
return handle != other.handle;
}
bool operator<(const RefObject &other) const
inline bool operator<(const RefObject &other) const
{
return handle < other.handle;
}
@@ -90,7 +88,7 @@ public:
{
refCount++;
}
void removeRef()
inline void removeRef()
{
refCount--;
if (refCount.load() == 0)
@@ -222,11 +220,11 @@ public:
object->removeRef();
}
}
bool operator==(const RefPtr &other) const
inline bool operator==(const RefPtr &other) const
{
return object == other.object;
}
bool operator!=(const RefPtr &other) const
inline bool operator!=(const RefPtr &other) const
{
return object != other.object;
}
@@ -234,12 +232,12 @@ public:
{
return object < other.object;
}
T *operator->()
inline T *operator->()
{
assert(object != nullptr);
return object->getHandle();
}
const T *operator->() const
inline const T *operator->() const
{
assert(object != nullptr);
return object->getHandle();
@@ -248,11 +246,11 @@ public:
{
return object;
}
T *getHandle()
inline T *getHandle()
{
return object->getHandle();
}
const T *getHandle() const
inline const T *getHandle() const
{
return object->getHandle();
}
@@ -291,6 +289,14 @@ template <typename T>
class UniquePtr
{
public:
UniquePtr()
: handle(nullptr)
{
}
UniquePtr(nullptr_t)
: handle(nullptr)
{
}
UniquePtr(T *ptr)
: handle(ptr)
{
+2 -1
View File
@@ -3,4 +3,5 @@ target_sources(SeeleEngine
Component.h
Component.cpp
PrimitiveComponent.cpp
PrimitiveComponent.h)
PrimitiveComponent.h
PrimitiveUniformBufferLayout.h)
@@ -1,7 +1,9 @@
#pragma once
#include "Component.h"
#include "Graphics/GraphicsResources.h"
#include "Graphics/Mesh.h"
#include "Material/MaterialInstance.h"
#include "Graphics/MeshBatch.h"
namespace Seele
{
@@ -14,9 +16,10 @@ public:
Matrix4 getRenderMatrix();
private:
PMaterialInstance instance;
Gfx::PVertexBuffer vertexBuffer;
Gfx::PIndexBuffer indexBuffer;
Array<PMaterialInstance> materials;
Gfx::PUniformBuffer uniformBuffer;
Array<StaticMeshBatch> staticMeshes;
PMesh mesh;
friend class Scene;
};
DEFINE_REF(PrimitiveComponent);
@@ -0,0 +1,12 @@
#pragma once
#include "Graphics/GraphicsResources.h"
namespace Seele
{
struct PrimitiveUniformBuffer
{
Matrix4 localToWorld;
Vector4 worldToLocal;
Vector4 actorWorldPosition;
};
} // namespace Seele
+7 -6
View File
@@ -32,14 +32,15 @@ void Scene::addPrimitiveComponent(PPrimitiveComponent comp)
primitives.add(comp);
}
Map<PMaterial, DrawState> Scene::getMeshBatches()
Map<PMaterial, MeshBatch> Scene::getMeshBatches()
{
meshBatches.clear();
for (auto primitive : primitives)
{
PMaterialInstance matInstance = primitive->instance;
/* Array<PMaterial> materials = primitive->materials;
PMaterialInstance matInstance = primitive->;
PMaterial mat = matInstance->getBaseMaterial();
DrawInstance inst;
MeshBatch inst;
inst.instance = primitive->instance;
inst.vertexBuffer = primitive->vertexBuffer;
inst.indexBuffer = primitive->indexBuffer;
@@ -47,15 +48,15 @@ Map<PMaterial, DrawState> Scene::getMeshBatches()
if (meshBatches.find(mat) != meshBatches.end())
{
DrawState &state = meshBatches[mat];
MeshBatchElement &state = meshBatches[mat];
state.instances.add(inst);
}
else
{
DrawState state;
MeshBatchElement state;
state.instances.add(inst);
meshBatches[mat] = state;
}
}*/
}
return meshBatches;
}
+5 -3
View File
@@ -3,6 +3,8 @@
#include "Actor/Actor.h"
#include "Graphics/GraphicsResources.h"
#include "Components/PrimitiveComponent.h"
#include "Graphics/MeshBatch.h"
#include "Material/Material.h"
namespace Seele
{
@@ -18,11 +20,11 @@ public:
void addPrimitiveComponent(PPrimitiveComponent comp);
private:
Map<PMaterial, DrawState> meshBatches;
Map<PMaterial, MeshBatch> meshBatches;
Array<PActor> rootActors;
Array<PPrimitiveComponent> primitives;
const static int constant = 10;
public:
Map<PMaterial, DrawState> getMeshBatches();
Map<PMaterial, MeshBatch> getMeshBatches();
};
} // namespace Seele
+3
View File
@@ -1,9 +1,12 @@
#include "Graphics/RenderCore.h"
#include "Asset/AssetRegistry.h"
using namespace Seele;
int main()
{
RenderCore core;
core.init();
AssetRegistry::init("./");
AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\TestAssets\\Unbenannt.fbx");
core.renderLoop();
core.shutdown();
return 0;