Improving Material shader code generation
This commit is contained in:
@@ -11,16 +11,22 @@ target_sources(SeeleEngine
|
||||
MeshBatch.h
|
||||
RenderCore.h
|
||||
RenderCore.cpp
|
||||
RenderMaterial.h
|
||||
RenderMaterial.cpp
|
||||
RenderPath.h
|
||||
RenderPath.cpp
|
||||
SceneView.h
|
||||
SceneView.cpp
|
||||
SceneRenderPath.h
|
||||
SceneRenderPath.cpp
|
||||
ShaderCompiler.h
|
||||
ShaderCompiler.cpp
|
||||
View.h
|
||||
View.cpp
|
||||
VertexShaderInput.h
|
||||
VertexShaderInput.cpp
|
||||
StaticMeshVertexInput.h
|
||||
StaticMeshVertexInput.cpp
|
||||
Window.cpp
|
||||
Window.h
|
||||
WindowManager.h
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#include "Graphics.h"
|
||||
#include <map>
|
||||
#include "ShaderCompiler.h"
|
||||
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
Graphics::Graphics()
|
||||
{
|
||||
shaderCompiler = new ShaderCompiler(this);
|
||||
}
|
||||
|
||||
Graphics::~Graphics()
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "GraphicsResources.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "VertexShaderInput.h"
|
||||
#include "ShaderCompiler.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -19,6 +20,11 @@ public:
|
||||
{
|
||||
return queueMapping;
|
||||
}
|
||||
|
||||
PShaderCompiler getShaderCompiler() const
|
||||
{
|
||||
return shaderCompiler;
|
||||
}
|
||||
|
||||
virtual PWindow createWindow(const WindowCreateInfo &createInfo) = 0;
|
||||
virtual PViewport createViewport(PWindow owner, const ViewportCreateInfo &createInfo) = 0;
|
||||
@@ -47,6 +53,7 @@ public:
|
||||
|
||||
protected:
|
||||
QueueFamilyMapping queueMapping;
|
||||
PShaderCompiler shaderCompiler;
|
||||
friend class Window;
|
||||
};
|
||||
DEFINE_REF(Graphics);
|
||||
|
||||
@@ -100,6 +100,7 @@ struct ShaderCreateInfo
|
||||
Array<std::string> shaderCode;
|
||||
std::string entryPoint;
|
||||
Array<const char*> typeParameter;
|
||||
Map<const char*, const char*> defines;
|
||||
};
|
||||
|
||||
namespace Gfx
|
||||
|
||||
@@ -42,18 +42,37 @@ ShaderCollection& ShaderMap::createShaders(
|
||||
PGraphics graphics,
|
||||
RenderPassType renderPass,
|
||||
PMaterial material,
|
||||
PVertexShaderInput vertexInput,
|
||||
VertexInputType* vertexInput,
|
||||
bool bPositionOnly)
|
||||
{
|
||||
ShaderCollection& collection = shaders.add();
|
||||
collection.vertexDeclaration = bPositionOnly ? vertexInput->getPositionDeclaration() : vertexInput->getDeclaration();
|
||||
//collection.vertexDeclaration = bPositionOnly ? vertexInput->getPositionDeclaration() : vertexInput->getDeclaration();
|
||||
|
||||
ShaderCreateInfo createInfo;
|
||||
createInfo.entryPoint = "vertexMain";
|
||||
createInfo.typeParameter = {material->getMaterialName().c_str(), vertexInput->getName().c_str()};
|
||||
createInfo.typeParameter = {material->getName().c_str()};
|
||||
createInfo.defines["VERTEX_INPUT_IMPORT"] = vertexInput->getShaderFilename();
|
||||
createInfo.defines["MATERIAL_IMPORT"] = material->getName().c_str();
|
||||
createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "1";
|
||||
createInfo.defines["USE_INSTANCING"] = "0";
|
||||
|
||||
std::ifstream codeStream("./shaders/" + getShaderNameFromRenderPassType(renderPass), std::ios::ate);
|
||||
auto fileSize = codeStream.tellg();
|
||||
codeStream.seekg(0);
|
||||
Array<char> buffer(static_cast<uint32>(fileSize));
|
||||
codeStream.read(buffer.data(), fileSize);
|
||||
|
||||
createInfo.shaderCode.add(std::string(buffer.data()));
|
||||
|
||||
collection.vertexShader = graphics->createVertexShader(createInfo);
|
||||
|
||||
if(renderPass != RenderPassType::DepthPrepass)
|
||||
{
|
||||
createInfo.entryPoint = "fragmentMain";
|
||||
|
||||
collection.fragmentShader = graphics->createFragmentShader(createInfo);
|
||||
}
|
||||
|
||||
return collection;
|
||||
}
|
||||
void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorType type, uint32 arrayCount)
|
||||
@@ -108,8 +127,8 @@ void PipelineLayout::addPushConstants(const SePushConstantRange &pushConstant)
|
||||
pushConstants.add(pushConstant);
|
||||
}
|
||||
|
||||
QueueOwnedResource::QueueOwnedResource(PGraphics graphics, QueueType startQueueType)
|
||||
: graphics(graphics)
|
||||
QueueOwnedResource::QueueOwnedResource(QueueFamilyMapping mapping, QueueType startQueueType)
|
||||
: mapping(mapping)
|
||||
, currentOwner(startQueueType)
|
||||
{
|
||||
}
|
||||
@@ -120,15 +139,15 @@ QueueOwnedResource::~QueueOwnedResource()
|
||||
|
||||
void QueueOwnedResource::transferOwnership(QueueType newOwner)
|
||||
{
|
||||
if(graphics->getFamilyMapping().needsTransfer(currentOwner, newOwner))
|
||||
if(mapping.needsTransfer(currentOwner, newOwner))
|
||||
{
|
||||
executeOwnershipBarrier(newOwner);
|
||||
currentOwner = newOwner;
|
||||
}
|
||||
}
|
||||
|
||||
Buffer::Buffer(PGraphics graphics, QueueType startQueue)
|
||||
: QueueOwnedResource(graphics, startQueue)
|
||||
Buffer::Buffer(QueueFamilyMapping mapping, QueueType startQueue)
|
||||
: QueueOwnedResource(mapping, startQueue)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -136,31 +155,32 @@ Buffer::~Buffer()
|
||||
{
|
||||
}
|
||||
|
||||
UniformBuffer::UniformBuffer(PGraphics graphics, QueueType startQueueType)
|
||||
: Buffer(graphics, startQueueType)
|
||||
UniformBuffer::UniformBuffer(QueueFamilyMapping mapping, QueueType startQueueType)
|
||||
: Buffer(mapping, startQueueType)
|
||||
{
|
||||
}
|
||||
|
||||
UniformBuffer::~UniformBuffer()
|
||||
{
|
||||
}
|
||||
StructuredBuffer::StructuredBuffer(PGraphics graphics, QueueType startQueueType)
|
||||
: Buffer(graphics, startQueueType)
|
||||
StructuredBuffer::StructuredBuffer(QueueFamilyMapping mapping, QueueType startQueueType)
|
||||
: Buffer(mapping, startQueueType)
|
||||
{
|
||||
}
|
||||
StructuredBuffer::~StructuredBuffer()
|
||||
{
|
||||
}
|
||||
VertexBuffer::VertexBuffer(PGraphics graphics, uint32 numVertices, uint32 vertexSize, QueueType startQueueType)
|
||||
: Buffer(graphics, startQueueType)
|
||||
, numVertices(numVertices), vertexSize(vertexSize)
|
||||
VertexBuffer::VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType)
|
||||
: Buffer(mapping, startQueueType)
|
||||
, numVertices(numVertices)
|
||||
, vertexSize(vertexSize)
|
||||
{
|
||||
}
|
||||
VertexBuffer::~VertexBuffer()
|
||||
{
|
||||
}
|
||||
IndexBuffer::IndexBuffer(PGraphics graphics, uint32 size, Gfx::SeIndexType indexType, QueueType startQueueType)
|
||||
: Buffer(graphics, startQueueType)
|
||||
IndexBuffer::IndexBuffer(QueueFamilyMapping mapping, uint32 size, Gfx::SeIndexType indexType, QueueType startQueueType)
|
||||
: Buffer(mapping, startQueueType)
|
||||
, indexType(indexType)
|
||||
{
|
||||
switch (indexType)
|
||||
@@ -179,8 +199,8 @@ IndexBuffer::~IndexBuffer()
|
||||
}
|
||||
VertexStream::VertexStream()
|
||||
{}
|
||||
VertexStream::VertexStream(uint32 stride, uint32 offset, uint8 instanced, Gfx::PVertexBuffer vertexBuffer)
|
||||
: stride(stride), instanced(instanced), offset(offset), vertexBuffer(vertexBuffer)
|
||||
VertexStream::VertexStream(uint32 stride, uint32 offset, uint8 instanced)
|
||||
: stride(stride), instanced(instanced), offset(offset)
|
||||
{
|
||||
}
|
||||
VertexStream::~VertexStream()
|
||||
@@ -200,19 +220,19 @@ VertexDeclaration::VertexDeclaration()
|
||||
VertexDeclaration::~VertexDeclaration()
|
||||
{
|
||||
}
|
||||
uint32 VertexDeclaration::addVertexStream(const VertexStream &element)
|
||||
uint32 VertexDeclaration::addVertexStream(const VertexStreamComponent &element)
|
||||
{
|
||||
uint32 currIndex = vertexStreams.size();
|
||||
vertexStreams.add(element);
|
||||
return currIndex;
|
||||
VertexStream& stream = vertexStreams.add();
|
||||
stream.addVertexElement(VertexElement(element.streamOffset, element.type, element.offset));
|
||||
return stream.vertexDescription.size() - 1;
|
||||
}
|
||||
const Array<VertexStream> &VertexDeclaration::getVertexStreams() const
|
||||
{
|
||||
return vertexStreams;
|
||||
}
|
||||
|
||||
Texture::Texture(PGraphics graphics, Gfx::QueueType startQueueType)
|
||||
: QueueOwnedResource(graphics, startQueueType)
|
||||
Texture::Texture(QueueFamilyMapping mapping, Gfx::QueueType startQueueType)
|
||||
: QueueOwnedResource(mapping, startQueueType)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -220,8 +240,8 @@ Texture::~Texture()
|
||||
{
|
||||
}
|
||||
|
||||
Texture2D::Texture2D(PGraphics graphics, Gfx::QueueType startQueueType)
|
||||
: Texture(graphics, startQueueType)
|
||||
Texture2D::Texture2D(QueueFamilyMapping mapping, Gfx::QueueType startQueueType)
|
||||
: Texture(mapping, startQueueType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -6,13 +6,16 @@
|
||||
#include "MeshBatch.h"
|
||||
#include <boost/crc.hpp>
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define ENABLE_VALIDATION
|
||||
|
||||
#ifdef DEBUG
|
||||
#endif
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
struct VertexInputStream;
|
||||
struct VertexStreamComponent;
|
||||
class VertexInputType;
|
||||
namespace Gfx
|
||||
{
|
||||
DECLARE_REF(Graphics);
|
||||
@@ -111,7 +114,7 @@ struct PermutationId
|
||||
struct ShaderCollection
|
||||
{
|
||||
PermutationId id;
|
||||
PVertexDeclaration vertexDeclaration;
|
||||
//PVertexDeclaration vertexDeclaration;
|
||||
PVertexShader vertexShader;
|
||||
PControlShader controlShader;
|
||||
PEvaluationShader evalutionShader;
|
||||
@@ -128,7 +131,7 @@ public:
|
||||
PGraphics graphics,
|
||||
RenderPassType passName,
|
||||
PMaterial material,
|
||||
PVertexShaderInput vertexInput,
|
||||
VertexInputType* vertexInput,
|
||||
bool bPositionOnly);
|
||||
private:
|
||||
Array<ShaderCollection> shaders;
|
||||
@@ -272,7 +275,7 @@ struct QueueFamilyMapping
|
||||
class QueueOwnedResource
|
||||
{
|
||||
public:
|
||||
QueueOwnedResource(PGraphics graphics, QueueType startQueueType);
|
||||
QueueOwnedResource(QueueFamilyMapping mapping, QueueType startQueueType);
|
||||
virtual ~QueueOwnedResource();
|
||||
|
||||
//Preliminary checks to see if the barrier should be executed at all
|
||||
@@ -281,14 +284,20 @@ public:
|
||||
protected:
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
Gfx::QueueType currentOwner;
|
||||
PGraphics graphics;
|
||||
QueueFamilyMapping mapping;
|
||||
};
|
||||
DEFINE_REF(QueueOwnedResource);
|
||||
|
||||
// IMPORTANT!!
|
||||
// WHEN DERIVING FROM ANY Gfx:: BASE CLASSES WITH MULTIPLE INHERITANCE
|
||||
// ALWAYS PUT THE Gfx:: BASE CLASS FIRST
|
||||
// This is because the refcounting object is unique per allocation, so
|
||||
// the base address of both the Gfx:: and the implementation class
|
||||
// need to match for it to work
|
||||
class Buffer : public QueueOwnedResource
|
||||
{
|
||||
public:
|
||||
Buffer(PGraphics graphics, QueueType startQueueType);
|
||||
Buffer(QueueFamilyMapping mapping, QueueType startQueueType);
|
||||
virtual ~Buffer();
|
||||
|
||||
protected:
|
||||
@@ -299,7 +308,7 @@ protected:
|
||||
class UniformBuffer : public Buffer
|
||||
{
|
||||
public:
|
||||
UniformBuffer(PGraphics graphics, QueueType startQueueType);
|
||||
UniformBuffer(QueueFamilyMapping mapping, QueueType startQueueType);
|
||||
virtual ~UniformBuffer();
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
@@ -310,7 +319,7 @@ DEFINE_REF(UniformBuffer);
|
||||
class VertexBuffer : public Buffer
|
||||
{
|
||||
public:
|
||||
VertexBuffer(PGraphics graphics, uint32 numVertices, uint32 vertexSize, QueueType startQueueType);
|
||||
VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType);
|
||||
virtual ~VertexBuffer();
|
||||
inline uint32 getNumVertices()
|
||||
{
|
||||
@@ -333,7 +342,7 @@ DEFINE_REF(VertexBuffer);
|
||||
class IndexBuffer : public Buffer
|
||||
{
|
||||
public:
|
||||
IndexBuffer(PGraphics graphics, uint32 size, Gfx::SeIndexType index, QueueType startQueueType);
|
||||
IndexBuffer(QueueFamilyMapping mapping, uint32 size, Gfx::SeIndexType index, QueueType startQueueType);
|
||||
virtual ~IndexBuffer();
|
||||
inline uint32 getNumIndices() const
|
||||
{
|
||||
@@ -355,7 +364,7 @@ DEFINE_REF(IndexBuffer);
|
||||
class StructuredBuffer : public Buffer
|
||||
{
|
||||
public:
|
||||
StructuredBuffer(PGraphics graphics, QueueType startQueueType);
|
||||
StructuredBuffer(QueueFamilyMapping mapping, QueueType startQueueType);
|
||||
virtual ~StructuredBuffer();
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
@@ -367,7 +376,7 @@ class VertexStream
|
||||
{
|
||||
public:
|
||||
VertexStream();
|
||||
VertexStream(uint32 stride, uint32 offset, uint8 instanced, Gfx::PVertexBuffer vertexBuffer);
|
||||
VertexStream(uint32 stride, uint32 offset, uint8 instanced);
|
||||
~VertexStream();
|
||||
void addVertexElement(VertexElement element);
|
||||
const Array<VertexElement> getVertexDescriptions() const;
|
||||
@@ -377,7 +386,6 @@ public:
|
||||
uint32 offset;
|
||||
Array<VertexElement> vertexDescription;
|
||||
uint8 instanced;
|
||||
PVertexBuffer vertexBuffer;
|
||||
};
|
||||
DEFINE_REF(VertexStream);
|
||||
class VertexDeclaration
|
||||
@@ -385,7 +393,7 @@ class VertexDeclaration
|
||||
public:
|
||||
VertexDeclaration();
|
||||
~VertexDeclaration();
|
||||
uint32 addVertexStream(const VertexStream &vertexStream);
|
||||
uint32 addVertexStream(const VertexStreamComponent &vertexStream);
|
||||
const Array<VertexStream> &getVertexStreams() const;
|
||||
|
||||
private:
|
||||
@@ -404,10 +412,17 @@ protected:
|
||||
GraphicsPipelineCreateInfo createInfo;
|
||||
};
|
||||
DEFINE_REF(GraphicsPipeline);
|
||||
|
||||
// IMPORTANT!!
|
||||
// WHEN DERIVING FROM ANY Gfx:: BASE CLASSES WITH MULTIPLE INHERITANCE
|
||||
// ALWAYS PUT THE Gfx:: BASE CLASS FIRST
|
||||
// This is because the refcounting object is unique per allocation, so
|
||||
// the base address of both the Gfx:: and the implementation class
|
||||
// need to match for it to work
|
||||
class Texture : public QueueOwnedResource
|
||||
{
|
||||
public:
|
||||
Texture(PGraphics graphics, QueueType startQueueType);
|
||||
Texture(QueueFamilyMapping mapping, QueueType startQueueType);
|
||||
virtual ~Texture();
|
||||
|
||||
virtual SeFormat getFormat() const = 0;
|
||||
@@ -422,7 +437,7 @@ DEFINE_REF(Texture);
|
||||
class Texture2D : public Texture
|
||||
{
|
||||
public:
|
||||
Texture2D(PGraphics graphics, QueueType startQueueType);
|
||||
Texture2D(QueueFamilyMapping mapping, QueueType startQueueType);
|
||||
virtual ~Texture2D();
|
||||
|
||||
virtual SeFormat getFormat() const = 0;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
Mesh::Mesh(MeshDescription description, Gfx::PIndexBuffer indexBuffer)
|
||||
: description(description)
|
||||
Mesh::Mesh(PVertexShaderInput vertexInput, Gfx::PIndexBuffer indexBuffer)
|
||||
: vertexInput(vertexInput)
|
||||
, indexBuffer(indexBuffer)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
#define MAX_TEX_CHANNELS 8
|
||||
/*#define MAX_TEX_CHANNELS 8
|
||||
struct MeshDescription
|
||||
{
|
||||
Array<Gfx::VertexAttribute> layout;
|
||||
@@ -41,23 +41,22 @@ struct MeshDescription
|
||||
ar & layout;
|
||||
//TODO declaration
|
||||
}
|
||||
};
|
||||
};*/
|
||||
DECLARE_REF(MaterialAsset);
|
||||
class Mesh
|
||||
{
|
||||
public:
|
||||
Mesh(MeshDescription description, Gfx::PIndexBuffer indexBuffer);
|
||||
Mesh(PVertexShaderInput vertexInput, Gfx::PIndexBuffer indexBuffer);
|
||||
~Mesh();
|
||||
|
||||
Gfx::PIndexBuffer indexBuffer;
|
||||
MeshDescription description;
|
||||
PVertexShaderInput vertexInput;
|
||||
PMaterialAsset referencedMaterial;
|
||||
private:
|
||||
friend class boost::serialization::access;
|
||||
template<class Archive>
|
||||
void serialize(Archive& ar, const unsigned int version)
|
||||
{
|
||||
ar & description;
|
||||
ar & referencedMaterial->getFullPath();
|
||||
//TODO:
|
||||
}
|
||||
|
||||
@@ -12,21 +12,6 @@ Seele::RenderCore::~RenderCore()
|
||||
|
||||
void Seele::RenderCore::init()
|
||||
{
|
||||
WindowCreateInfo mainWindowInfo;
|
||||
mainWindowInfo.title = "SeeleEngine";
|
||||
mainWindowInfo.width = 1280;
|
||||
mainWindowInfo.height = 720;
|
||||
mainWindowInfo.bFullscreen = false;
|
||||
mainWindowInfo.numSamples = 1;
|
||||
mainWindowInfo.pixelFormat = Gfx::SE_FORMAT_R8G8B8_UNORM;
|
||||
auto window = windowManager->addWindow(mainWindowInfo);
|
||||
ViewportCreateInfo sceneViewInfo;
|
||||
sceneViewInfo.sizeX = 1280;
|
||||
sceneViewInfo.sizeY = 720;
|
||||
sceneViewInfo.offsetX = 0;
|
||||
sceneViewInfo.offsetY = 0;
|
||||
PSceneView sceneView = new SceneView(windowManager->getGraphics(), window, sceneViewInfo);
|
||||
window->addView(sceneView);
|
||||
}
|
||||
|
||||
void Seele::RenderCore::renderLoop()
|
||||
@@ -34,6 +19,7 @@ void Seele::RenderCore::renderLoop()
|
||||
while (windowManager->isActive())
|
||||
{
|
||||
windowManager->beginFrame();
|
||||
windowManager->render();
|
||||
windowManager->endFrame();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ public:
|
||||
void renderLoop();
|
||||
void shutdown();
|
||||
|
||||
PWindowManager getWindowManager() const { return windowManager; };
|
||||
private:
|
||||
PScene scene;
|
||||
PWindowManager windowManager;
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#include "RenderMaterial.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
#include "GraphicsResources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Gfx
|
||||
{
|
||||
class MaterialShaderMap;//TODO implement
|
||||
class MaterialRenderContext;
|
||||
struct UniformExpressionCache
|
||||
{
|
||||
Gfx::PUniformBuffer uniformBuffer;
|
||||
uint8 bUpToDate;
|
||||
|
||||
const MaterialShaderMap* cachedUniformExpressionShaderMap;
|
||||
};
|
||||
class Material;
|
||||
class RenderMaterial
|
||||
{
|
||||
public:
|
||||
mutable UniformExpressionCache uniformExpressionCache;
|
||||
RenderMaterial();
|
||||
virtual ~RenderMaterial();
|
||||
|
||||
void evaluateUniformExpressions(UniformExpressionCache& outUniforExpressionCache, const MaterialRenderContext& context);
|
||||
|
||||
void cacheUniformExpressions(bool bRecreatueUniformBuffer);
|
||||
|
||||
void invalidateUniformExpressionCache(bool bRecreateUniformBuffer);
|
||||
|
||||
void updateUniformExpressionCacheIfNeeded() const;
|
||||
|
||||
const Material* getMaterial() const
|
||||
{
|
||||
const RenderMaterial* unused = nullptr;
|
||||
return &getMaterialWithFallback(unused);
|
||||
}
|
||||
|
||||
virtual const Material& getMaterialWithFallback(const RenderMaterial*& outFallbackRenderMaterial) const = 0;
|
||||
|
||||
virtual Material* getMaterialNoFallback() const { return nullptr; }
|
||||
};
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
@@ -27,7 +27,8 @@ void BasePassMeshProcessor::addMeshBatch(
|
||||
|
||||
//TODO query tesselation
|
||||
|
||||
const Gfx::ShaderCollection* collection = material->getShaders(Gfx::RenderPassType::BasePass, vertexInput);
|
||||
const Gfx::ShaderCollection* collection = material->getShaders(Gfx::RenderPassType::BasePass, vertexInput->getType());
|
||||
assert(collection != nullptr);
|
||||
Gfx::PRenderCommand renderCommand = graphics->createRenderCommand();
|
||||
buildMeshDrawCommand(batch,
|
||||
primitiveComponent,
|
||||
@@ -79,12 +80,9 @@ void BasePass::render()
|
||||
{
|
||||
processor->clearCommands();
|
||||
graphics->beginRenderPass(renderPass);
|
||||
for (auto &&primitive : scene->getPrimitives())
|
||||
for (auto &&primitive : scene->getStaticMeshes())
|
||||
{
|
||||
for (auto &&meshBatch : primitive->staticMeshes)
|
||||
{
|
||||
processor->addMeshBatch(meshBatch, primitive, renderPass);
|
||||
}
|
||||
processor->addMeshBatch(primitive, nullptr, renderPass);
|
||||
}
|
||||
graphics->executeCommands(processor->getRenderCommands());
|
||||
graphics->endRenderPass();
|
||||
|
||||
@@ -5,14 +5,11 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
SceneRenderPath::SceneRenderPath(Gfx::PGraphics graphics, Gfx::PViewport target)
|
||||
SceneRenderPath::SceneRenderPath(PScene scene, Gfx::PGraphics graphics, Gfx::PViewport target)
|
||||
: RenderPath(graphics, target)
|
||||
, basePass(new BasePass(scene, graphics, target))
|
||||
, scene(scene)
|
||||
{
|
||||
scene = new Scene();
|
||||
PMeshAsset asset = AssetRegistry::findMesh("Unbenannt");
|
||||
PActor rootActor = new Actor();
|
||||
PPrimitiveComponent primitiveComponent = new PrimitiveComponent();
|
||||
basePass = new BasePass(scene, graphics, target);
|
||||
}
|
||||
|
||||
SceneRenderPath::~SceneRenderPath()
|
||||
|
||||
@@ -8,7 +8,7 @@ DECLARE_REF(Scene);
|
||||
class SceneRenderPath : public RenderPath
|
||||
{
|
||||
public:
|
||||
SceneRenderPath(Gfx::PGraphics graphics, Gfx::PViewport target);
|
||||
SceneRenderPath(PScene scene, Gfx::PGraphics graphics, Gfx::PViewport target);
|
||||
virtual ~SceneRenderPath();
|
||||
void setTargetScene(PScene scene);
|
||||
virtual void init();
|
||||
|
||||
@@ -8,7 +8,8 @@ using namespace Seele;
|
||||
Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo)
|
||||
: View(graphics, owner, createInfo)
|
||||
{
|
||||
renderer = new SceneRenderPath(graphics, viewport);
|
||||
scene = new Scene(graphics);
|
||||
renderer = new SceneRenderPath(scene, graphics, viewport);
|
||||
}
|
||||
|
||||
Seele::SceneView::~SceneView()
|
||||
|
||||
@@ -2,11 +2,15 @@
|
||||
#include "View.h"
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_REF(Scene);
|
||||
class SceneView : public View
|
||||
{
|
||||
public:
|
||||
SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo);
|
||||
~SceneView();
|
||||
PScene getScene() const { return scene; }
|
||||
private:
|
||||
PScene scene;
|
||||
};
|
||||
DEFINE_REF(SceneView);
|
||||
} // namespace Seele
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "ShaderCompiler.h"
|
||||
#include "Material/Material.h"
|
||||
#include "VertexShaderInput.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
ShaderCompiler::ShaderCompiler(PGraphics graphics)
|
||||
: graphics(graphics)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ShaderCompiler::~ShaderCompiler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ShaderCompiler::registerMaterial(PMaterial material)
|
||||
{
|
||||
for(auto type : VertexInputType::getTypeList())
|
||||
{
|
||||
material->createShaders(graphics, Gfx::RenderPassType::DepthPrepass, type);
|
||||
material->createShaders(graphics, Gfx::RenderPassType::BasePass, type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include "GraphicsResources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_REF(Material);
|
||||
DECLARE_NAME_REF(Gfx, Graphics);
|
||||
namespace Gfx
|
||||
{
|
||||
class ShaderCompiler
|
||||
{
|
||||
public:
|
||||
ShaderCompiler(PGraphics graphics);
|
||||
~ShaderCompiler();
|
||||
void registerMaterial(PMaterial material);
|
||||
private:
|
||||
Array<PMaterial> pendingCompiles;
|
||||
PGraphics graphics;
|
||||
};
|
||||
DEFINE_REF(ShaderCompiler);
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
@@ -0,0 +1,48 @@
|
||||
#include "StaticMeshVertexInput.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
StaticMeshVertexInput::StaticMeshVertexInput(std::string name)
|
||||
: VertexShaderInput(name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
StaticMeshVertexInput::~StaticMeshVertexInput()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void StaticMeshVertexInput::setPositionStream(const VertexStreamComponent& positionStream)
|
||||
{
|
||||
declaration->addVertexStream(positionStream);
|
||||
positionDeclaration->addVertexStream(positionStream);
|
||||
data.positionStream = positionStream;
|
||||
}
|
||||
|
||||
void StaticMeshVertexInput::setTangentXStream(const VertexStreamComponent& tangentXStream)
|
||||
{
|
||||
declaration->addVertexStream(tangentXStream);
|
||||
data.tangentBasisComponents[0] = tangentXStream;
|
||||
}
|
||||
|
||||
void StaticMeshVertexInput::setTangentZStream(const VertexStreamComponent& tangentZStream)
|
||||
{
|
||||
declaration->addVertexStream(tangentZStream);
|
||||
data.tangentBasisComponents[1] = tangentZStream;
|
||||
}
|
||||
|
||||
void StaticMeshVertexInput::setTexCoordStream(uint32 index, const VertexStreamComponent& textureStream)
|
||||
{
|
||||
//TODO: replace add with proper indexing
|
||||
declaration->addVertexStream(textureStream);
|
||||
data.textureCoordinates.add(textureStream);
|
||||
}
|
||||
|
||||
void StaticMeshVertexInput::setColorStream(const VertexStreamComponent& colorStream)
|
||||
{
|
||||
declaration->addVertexStream(colorStream);
|
||||
data.colorComponent = colorStream;
|
||||
}
|
||||
|
||||
IMPLEMENT_VERTEX_INPUT_TYPE(StaticMeshVertexInput, "StaticMeshVertexInput");
|
||||
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
#include "VertexShaderInput.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
enum { MAX_TEXCOORDS = 4 };
|
||||
struct StaticMeshDataType
|
||||
{
|
||||
VertexStreamComponent positionStream;
|
||||
VertexStreamComponent tangentBasisComponents[2];
|
||||
|
||||
//Dont forget these are 4 component vectors
|
||||
Array<VertexStreamComponent> textureCoordinates;
|
||||
|
||||
VertexStreamComponent colorComponent;
|
||||
};
|
||||
class StaticMeshVertexInput : public VertexShaderInput
|
||||
{
|
||||
DECLARE_VERTEX_INPUT_TYPE(StaticMeshVertexInput);
|
||||
public:
|
||||
StaticMeshVertexInput(std::string name);
|
||||
virtual ~StaticMeshVertexInput();
|
||||
void setPositionStream(const VertexStreamComponent& positionStream);
|
||||
void setTangentXStream(const VertexStreamComponent& tangentXStream);
|
||||
void setTangentZStream(const VertexStreamComponent& tangentZStream);
|
||||
void setTexCoordStream(uint32 index, const VertexStreamComponent& textureStream);
|
||||
void setColorStream(const VertexStreamComponent& colorStream);
|
||||
private:
|
||||
StaticMeshDataType data;
|
||||
};
|
||||
DEFINE_REF(StaticMeshVertexInput);
|
||||
}
|
||||
@@ -5,49 +5,64 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
List<PVertexShaderInput> VertexShaderInput::registeredInputs;
|
||||
std::mutex VertexShaderInput::registeredInputsLock;
|
||||
List<VertexInputType*> VertexInputType::globalTypeList;
|
||||
|
||||
List<VertexInputType*> VertexInputType::getTypeList()
|
||||
{
|
||||
return globalTypeList;
|
||||
}
|
||||
|
||||
VertexInputType* VertexInputType::getVertexInputByName(const std::string& name)
|
||||
{
|
||||
for(auto type : globalTypeList)
|
||||
{
|
||||
if(name.compare(type->getName()) == 0)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
VertexInputType::VertexInputType(const char* name,
|
||||
const char* shaderFilename)
|
||||
: name(name)
|
||||
, shaderFilename(shaderFilename)
|
||||
{
|
||||
globalTypeList.add(this);
|
||||
}
|
||||
|
||||
VertexInputType::~VertexInputType()
|
||||
{
|
||||
globalTypeList.remove(globalTypeList.find(this));
|
||||
}
|
||||
|
||||
const char* VertexInputType::getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
const char* VertexInputType::getShaderFilename()
|
||||
{
|
||||
return shaderFilename;
|
||||
}
|
||||
|
||||
VertexShaderInput::VertexShaderInput(std::string name)
|
||||
: name(name)
|
||||
{
|
||||
std::scoped_lock lock(registeredInputsLock);
|
||||
registeredInputs.add(this);
|
||||
}
|
||||
|
||||
VertexShaderInput::VertexShaderInput(MeshDescription description, std::string name)
|
||||
: declaration(description.declaration)
|
||||
, layout(description.layout)
|
||||
, name(name)
|
||||
{
|
||||
auto declStreams = declaration->getVertexStreams();
|
||||
std::copy(declStreams.begin(), declStreams.end(), streams.begin());
|
||||
|
||||
uint32 positionStreamIndex = 0;
|
||||
declaration = new Gfx::VertexDeclaration();
|
||||
positionDeclaration = new Gfx::VertexDeclaration();
|
||||
for (uint32 i = 0; i < declStreams.size(); i++)
|
||||
{
|
||||
if(description.layout[i] == Gfx::VertexAttribute::POSITION)
|
||||
{
|
||||
positionStreams[positionStreamIndex++] = declStreams[i];
|
||||
positionDeclaration->addVertexStream(declStreams[i]);
|
||||
}
|
||||
}
|
||||
|
||||
std::scoped_lock lock(registeredInputsLock);
|
||||
registeredInputs.add(this);
|
||||
}
|
||||
|
||||
VertexShaderInput::~VertexShaderInput()
|
||||
{
|
||||
registeredInputs.remove(registeredInputs.find(this));
|
||||
}
|
||||
|
||||
void VertexShaderInput::getStreams(VertexInputStreamArray& outVertexStreams) const
|
||||
{
|
||||
for(uint32 i = 0; i < streams.size(); ++i)
|
||||
{
|
||||
const Gfx::VertexStream& stream = streams[i];
|
||||
const VertexInputStream& stream = streams[i];
|
||||
if(stream.vertexBuffer == nullptr)
|
||||
{
|
||||
outVertexStreams.add(VertexInputStream(i, 0, nullptr));
|
||||
@@ -63,7 +78,7 @@ void VertexShaderInput::getPositionOnlyStream(VertexInputStreamArray& outVertexS
|
||||
{
|
||||
for (uint32 i = 0; i < positionStreams.size(); ++i)
|
||||
{
|
||||
const Gfx::VertexStream& stream = positionStreams[i];
|
||||
const VertexInputStream& stream = positionStreams[i];
|
||||
outVertexStreams.add(VertexInputStream(i, stream.offset, stream.vertexBuffer));
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
// Minimal vertex source used for building commands
|
||||
struct VertexInputStream
|
||||
{
|
||||
uint32 streamIndex : 4;
|
||||
@@ -35,33 +36,103 @@ struct VertexInputStream
|
||||
return !(*this == rhs);
|
||||
}
|
||||
};
|
||||
typedef Array<VertexInputStream> VertexInputStreamArray; //TODO inline allocation
|
||||
|
||||
// Typed data source for a vertex factory
|
||||
struct VertexStreamComponent
|
||||
{
|
||||
// Source vertex buffer
|
||||
Gfx::PVertexBuffer vertexBuffer = nullptr;
|
||||
|
||||
// Offset to the start of the vertex buffer fetch
|
||||
uint32 streamOffset = 0;
|
||||
|
||||
// Offset of the data, relative to the beginnning of each element in the vertex buffer
|
||||
uint32 offset = 0;
|
||||
|
||||
// Stride of the data
|
||||
uint32 stride = 0;
|
||||
|
||||
Gfx::SeFormat type = Gfx::SE_FORMAT_UNDEFINED;
|
||||
|
||||
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)
|
||||
{}
|
||||
};
|
||||
|
||||
#define STRUCTMEMBER_VERTEXSTREAMCOMPONENT(vertexBuffer, vertexType, member, memberType) \
|
||||
VertexStreamComponent(vertexBuffer, offsetof(vertexType, member), sizeof(vertexType), memberType)
|
||||
|
||||
class VertexInputType
|
||||
{
|
||||
public:
|
||||
static List<VertexInputType*> getTypeList();
|
||||
static VertexInputType* getVertexInputByName(const std::string& name);
|
||||
|
||||
VertexInputType(
|
||||
const char* name,
|
||||
const char* shaderFilename
|
||||
);
|
||||
virtual ~VertexInputType();
|
||||
|
||||
const char* getName();
|
||||
const char* getShaderFilename();
|
||||
private:
|
||||
const char* name;
|
||||
const char* shaderFilename;
|
||||
|
||||
static List<VertexInputType*> globalTypeList;
|
||||
};
|
||||
|
||||
#define DECLARE_VERTEX_INPUT_TYPE(inputClass) \
|
||||
public: \
|
||||
static VertexInputType staticType; \
|
||||
virtual VertexInputType* getType() const override;
|
||||
|
||||
#define IMPLEMENT_VERTEX_INPUT_TYPE(inputClass, shaderFilename) \
|
||||
VertexInputType inputClass::staticType( \
|
||||
#inputClass, \
|
||||
shaderFilename); \
|
||||
VertexInputType* inputClass::getType() const { return &staticType; }
|
||||
|
||||
typedef Array<VertexInputStream> VertexInputStreamArray;
|
||||
struct MeshDescription;
|
||||
DECLARE_REF(VertexShaderInput);
|
||||
class VertexShaderInput
|
||||
{
|
||||
public:
|
||||
VertexShaderInput(std::string name);
|
||||
VertexShaderInput(MeshDescription description, std::string name);
|
||||
~VertexShaderInput();
|
||||
virtual ~VertexShaderInput();
|
||||
void getStreams(VertexInputStreamArray& outVertexStreams) const;
|
||||
void getPositionOnlyStream(VertexInputStreamArray& outVertexStreams) const;
|
||||
virtual bool supportsTesselation() { return false; }
|
||||
virtual VertexInputType* getType() const { return nullptr; }
|
||||
Gfx::PVertexDeclaration getDeclaration() const {return declaration;}
|
||||
Gfx::PVertexDeclaration getPositionDeclaration() const {return positionDeclaration;}
|
||||
std::string getName() const { return name; }
|
||||
std::string getCode() const { return code; }
|
||||
private:
|
||||
protected:
|
||||
static List<PVertexShaderInput> registeredInputs;
|
||||
static std::mutex registeredInputsLock;
|
||||
Array<Gfx::VertexAttribute> layout;
|
||||
StaticArray<Gfx::VertexStream, 16> streams;
|
||||
StaticArray<Gfx::VertexStream, 16> positionStreams;
|
||||
StaticArray<VertexInputStream, 16> streams;
|
||||
StaticArray<VertexInputStream, 16> positionStreams;
|
||||
Gfx::PVertexDeclaration declaration;
|
||||
Gfx::PVertexDeclaration positionDeclaration;
|
||||
std::string name;
|
||||
std::string code;
|
||||
};
|
||||
DEFINE_REF(VertexShaderInput);
|
||||
} // namespace Seele
|
||||
|
||||
@@ -114,7 +114,7 @@ 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)
|
||||
if (freeRanges.find(allocation->allocatedOffset) != nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -286,6 +286,8 @@ void StagingManager::clearPending()
|
||||
|
||||
PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageFlags usage, bool bCPURead)
|
||||
{
|
||||
|
||||
std::unique_lock l(lock);
|
||||
for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it)
|
||||
{
|
||||
auto freeBuffer = *it;
|
||||
@@ -296,6 +298,7 @@ PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageF
|
||||
return freeBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
PStagingBuffer stagingBuffer = new StagingBuffer();
|
||||
VkBufferCreateInfo stagingBufferCreateInfo = init::BufferCreateInfo(usage, size);
|
||||
VkDevice vulkanDevice = graphics->getDevice();
|
||||
@@ -322,11 +325,13 @@ PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageF
|
||||
vkBindBufferMemory(graphics->getDevice(), stagingBuffer->buffer, stagingBuffer->getMemoryHandle(), stagingBuffer->getOffset());
|
||||
|
||||
activeBuffers.add(stagingBuffer.getHandle());
|
||||
|
||||
return stagingBuffer;
|
||||
}
|
||||
|
||||
void StagingManager::releaseStagingBuffer(PStagingBuffer buffer)
|
||||
{
|
||||
std::unique_lock l(lock);
|
||||
freeBuffers.add(buffer);
|
||||
activeBuffers.remove(activeBuffers.find(buffer.getHandle()));
|
||||
}
|
||||
@@ -213,6 +213,7 @@ private:
|
||||
PAllocator allocator;
|
||||
Array<PStagingBuffer> freeBuffers;
|
||||
Array<StagingBuffer *> activeBuffers;
|
||||
std::mutex lock;
|
||||
};
|
||||
DEFINE_REF(StagingManager);
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -14,9 +14,9 @@ struct PendingBuffer
|
||||
bool bWriteOnly;
|
||||
};
|
||||
|
||||
static Map<Buffer *, PendingBuffer> pendingBuffers;
|
||||
static Map<ShaderBuffer *, PendingBuffer> pendingBuffers;
|
||||
|
||||
Buffer::Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType)
|
||||
ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType)
|
||||
: graphics(graphics), currentBuffer(0), size(size), currentOwner(queueType)
|
||||
{
|
||||
if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ||
|
||||
@@ -56,21 +56,22 @@ Buffer::Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::Q
|
||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
}
|
||||
|
||||
Buffer::~Buffer()
|
||||
ShaderBuffer::~ShaderBuffer()
|
||||
{
|
||||
auto fence = graphics->getQueueCommands(currentOwner)->getCommands()->getFence();
|
||||
auto cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
|
||||
auto &deletionQueue = graphics->getDeletionQueue();
|
||||
VkDevice device = graphics->getDevice();
|
||||
VkBuffer buf[Gfx::numFramesBuffered];
|
||||
for (uint32 i = 0; i < numBuffers; ++i)
|
||||
{
|
||||
buf[i] = buffers[i].buffer;
|
||||
deletionQueue.addPendingDelete(fence, [device, buf, i]() { vkDestroyBuffer(device, buf[i], nullptr); });
|
||||
deletionQueue.addPendingDelete(cmdBuffer, [device, buf, i]() { vkDestroyBuffer(device, buf[i], nullptr); });
|
||||
buffers[i].allocation = nullptr;
|
||||
}
|
||||
graphics = nullptr;
|
||||
}
|
||||
|
||||
void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
{
|
||||
VkBufferMemoryBarrier barrier =
|
||||
init::BufferMemoryBarrier();
|
||||
@@ -137,7 +138,7 @@ void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
currentOwner = newOwner;
|
||||
}
|
||||
|
||||
void *Buffer::lock(bool bWriteOnly)
|
||||
void *ShaderBuffer::lock(bool bWriteOnly)
|
||||
{
|
||||
void *data = nullptr;
|
||||
|
||||
@@ -208,7 +209,7 @@ void *Buffer::lock(bool bWriteOnly)
|
||||
return data;
|
||||
}
|
||||
|
||||
void Buffer::unlock()
|
||||
void ShaderBuffer::unlock()
|
||||
{
|
||||
auto found = pendingBuffers.find(this);
|
||||
if (found != pendingBuffers.end())
|
||||
@@ -233,8 +234,8 @@ void Buffer::unlock()
|
||||
}
|
||||
|
||||
UniformBuffer::UniformBuffer(PGraphics graphics, const BulkResourceData &resourceData)
|
||||
: Buffer(graphics, resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, resourceData.owner)
|
||||
, Gfx::UniformBuffer(graphics, resourceData.owner)
|
||||
: Vulkan::ShaderBuffer(graphics, resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, resourceData.owner)
|
||||
, Gfx::UniformBuffer(graphics->getFamilyMapping(), resourceData.owner)
|
||||
{
|
||||
if (resourceData.data != nullptr)
|
||||
{
|
||||
@@ -251,12 +252,12 @@ UniformBuffer::~UniformBuffer()
|
||||
void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
|
||||
{
|
||||
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
||||
Buffer::currentOwner = newOwner;
|
||||
Vulkan::ShaderBuffer::currentOwner = newOwner;
|
||||
}
|
||||
|
||||
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
{
|
||||
Buffer::executeOwnershipBarrier(newOwner);
|
||||
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
VkAccessFlags UniformBuffer::getSourceAccessMask()
|
||||
@@ -270,8 +271,8 @@ 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)
|
||||
: Vulkan::ShaderBuffer(graphics, resourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, resourceData.owner)
|
||||
, Gfx::StructuredBuffer(graphics->getFamilyMapping(), resourceData.owner)
|
||||
{
|
||||
if (resourceData.data != nullptr)
|
||||
{
|
||||
@@ -292,7 +293,7 @@ void StructuredBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
|
||||
|
||||
void StructuredBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
{
|
||||
Buffer::executeOwnershipBarrier(newOwner);
|
||||
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
VkAccessFlags StructuredBuffer::getSourceAccessMask()
|
||||
@@ -306,8 +307,8 @@ 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(graphics, resourceData.numVertices, resourceData.vertexSize, resourceData.resourceData.owner)
|
||||
: Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, resourceData.resourceData.owner)
|
||||
, Gfx::VertexBuffer(graphics->getFamilyMapping(), resourceData.numVertices, resourceData.vertexSize, resourceData.resourceData.owner)
|
||||
{
|
||||
if (resourceData.resourceData.data != nullptr)
|
||||
{
|
||||
@@ -328,7 +329,7 @@ void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
|
||||
|
||||
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
{
|
||||
Buffer::executeOwnershipBarrier(newOwner);
|
||||
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
VkAccessFlags VertexBuffer::getSourceAccessMask()
|
||||
@@ -342,8 +343,8 @@ 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(graphics, resourceData.resourceData.size, resourceData.indexType, resourceData.resourceData.owner)
|
||||
: Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, resourceData.resourceData.owner)
|
||||
, Gfx::IndexBuffer(graphics->getFamilyMapping(), resourceData.resourceData.size, resourceData.indexType, resourceData.resourceData.owner)
|
||||
{
|
||||
if (resourceData.resourceData.data != nullptr)
|
||||
{
|
||||
@@ -364,7 +365,7 @@ void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
|
||||
|
||||
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
{
|
||||
Buffer::executeOwnershipBarrier(newOwner);
|
||||
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
VkAccessFlags IndexBuffer::getSourceAccessMask()
|
||||
|
||||
@@ -22,8 +22,8 @@ CmdBufferBase::~CmdBufferBase()
|
||||
graphics = nullptr;
|
||||
}
|
||||
|
||||
CmdBuffer::CmdBuffer(PGraphics graphics, VkCommandPool cmdPool)
|
||||
: CmdBufferBase(graphics, cmdPool), renderPass(nullptr), framebuffer(nullptr), subpassIndex(0)
|
||||
CmdBuffer::CmdBuffer(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferManager manager)
|
||||
: CmdBufferBase(graphics, cmdPool), renderPass(nullptr), framebuffer(nullptr), subpassIndex(0), manager(manager)
|
||||
{
|
||||
VkCommandBufferAllocateInfo allocInfo =
|
||||
init::CommandBufferAllocateInfo(cmdPool,
|
||||
@@ -120,6 +120,11 @@ PFence CmdBuffer::getFence()
|
||||
return fence;
|
||||
}
|
||||
|
||||
PCommandBufferManager CmdBuffer::getManager()
|
||||
{
|
||||
return manager;
|
||||
}
|
||||
|
||||
SecondaryCmdBuffer::SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool)
|
||||
: CmdBufferBase(graphics, cmdPool)
|
||||
{
|
||||
@@ -195,8 +200,9 @@ CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
|
||||
|
||||
VK_CHECK(vkCreateCommandPool(graphics->getDevice(), &info, nullptr, &commandPool));
|
||||
|
||||
activeCmdBuffer = new CmdBuffer(graphics, commandPool);
|
||||
activeCmdBuffer = new CmdBuffer(graphics, commandPool, this);
|
||||
activeCmdBuffer->begin();
|
||||
std::lock_guard lock(allocatedBufferLock);
|
||||
allocatedBuffers.add(activeCmdBuffer);
|
||||
}
|
||||
|
||||
@@ -236,6 +242,7 @@ void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
|
||||
queue->submitCommandBuffer(activeCmdBuffer);
|
||||
}
|
||||
}
|
||||
std::lock_guard lock(allocatedBufferLock);
|
||||
for (uint32 i = 0; i < allocatedBuffers.size(); ++i)
|
||||
{
|
||||
PCmdBuffer cmdBuffer = allocatedBuffers[i];
|
||||
@@ -251,7 +258,7 @@ void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
|
||||
assert(cmdBuffer->state == CmdBuffer::State::Submitted);
|
||||
}
|
||||
}
|
||||
activeCmdBuffer = new CmdBuffer(graphics, commandPool);
|
||||
activeCmdBuffer = new CmdBuffer(graphics, commandPool, this);
|
||||
allocatedBuffers.add(activeCmdBuffer);
|
||||
activeCmdBuffer->begin();
|
||||
}
|
||||
|
||||
@@ -30,10 +30,11 @@ protected:
|
||||
DEFINE_REF(CmdBufferBase);
|
||||
|
||||
DECLARE_REF(SecondaryCmdBuffer);
|
||||
DECLARE_REF(CommandBufferManager);
|
||||
class CmdBuffer : public CmdBufferBase
|
||||
{
|
||||
public:
|
||||
CmdBuffer(PGraphics graphics, VkCommandPool cmdPool);
|
||||
CmdBuffer(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferManager manager);
|
||||
virtual ~CmdBuffer();
|
||||
void begin();
|
||||
void end();
|
||||
@@ -43,6 +44,7 @@ public:
|
||||
void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
|
||||
void refreshFence();
|
||||
PFence getFence();
|
||||
PCommandBufferManager getManager();
|
||||
enum State
|
||||
{
|
||||
ReadyBegin,
|
||||
@@ -53,6 +55,7 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
PCommandBufferManager manager;
|
||||
PRenderPass renderPass;
|
||||
PFramebuffer framebuffer;
|
||||
PFence fence;
|
||||
@@ -105,6 +108,7 @@ private:
|
||||
PQueue queue;
|
||||
uint32 queueFamilyIndex;
|
||||
PCmdBuffer activeCmdBuffer;
|
||||
std::mutex allocatedBufferLock;
|
||||
Array<PCmdBuffer> allocatedBuffers;
|
||||
};
|
||||
DEFINE_REF(CommandBufferManager);
|
||||
|
||||
@@ -49,4 +49,5 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::PRende
|
||||
Framebuffer::~Framebuffer()
|
||||
{
|
||||
vkDestroyFramebuffer(graphics->getDevice(), handle, nullptr);
|
||||
graphics = nullptr;
|
||||
}
|
||||
@@ -64,6 +64,7 @@ void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
|
||||
if (found == allocatedFramebuffers.end())
|
||||
{
|
||||
framebuffer = new Framebuffer(this, rp, rp->getLayout());
|
||||
allocatedFramebuffers[framebufferHash] = framebuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -23,10 +23,10 @@ QueueOwnedResourceDeletion::~QueueOwnedResourceDeletion()
|
||||
worker.join();
|
||||
}
|
||||
|
||||
void QueueOwnedResourceDeletion::addPendingDelete(PFence fence, std::function<void()> func)
|
||||
void QueueOwnedResourceDeletion::addPendingDelete(PCmdBuffer cmdbuffer, std::function<void()> func)
|
||||
{
|
||||
PendingItem item;
|
||||
item.fence = fence;
|
||||
item.cmdBuffer = cmdbuffer;
|
||||
item.func = func;
|
||||
deletionQueue.add(item);
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
@@ -40,13 +40,12 @@ void QueueOwnedResourceDeletion::run()
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
cv.wait(lock);
|
||||
auto entry = deletionQueue.begin();
|
||||
PFence fence = entry->fence;
|
||||
fence->wait(1000ull);
|
||||
if (fence->isSignaled())
|
||||
{
|
||||
entry->func();
|
||||
deletionQueue.remove(entry);
|
||||
}
|
||||
PCmdBuffer cmdBuffer = entry->cmdBuffer;
|
||||
//cmdBuffer->getManager()->waitForCommands(cmdBuffer);
|
||||
//cmdBuffer->begin();
|
||||
|
||||
//entry->func();
|
||||
deletionQueue.remove(entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Vulkan
|
||||
|
||||
DECLARE_REF(DescriptorAllocator);
|
||||
DECLARE_REF(CommandBufferManager);
|
||||
DECLARE_REF(CmdBuffer);
|
||||
DECLARE_REF(Graphics);
|
||||
DECLARE_REF(SubAllocation);
|
||||
class Semaphore
|
||||
@@ -57,7 +58,7 @@ class QueueOwnedResourceDeletion
|
||||
public:
|
||||
QueueOwnedResourceDeletion();
|
||||
virtual ~QueueOwnedResourceDeletion();
|
||||
static void addPendingDelete(PFence fence, std::function<void()> function);
|
||||
static void addPendingDelete(PCmdBuffer fence, std::function<void()> function);
|
||||
|
||||
private:
|
||||
std::thread worker;
|
||||
@@ -65,7 +66,7 @@ private:
|
||||
static void run();
|
||||
struct PendingItem
|
||||
{
|
||||
PFence fence;
|
||||
PCmdBuffer cmdBuffer;
|
||||
std::function<void()> func;
|
||||
};
|
||||
static std::mutex mutex;
|
||||
@@ -73,11 +74,11 @@ private:
|
||||
static List<PendingItem> deletionQueue;
|
||||
};
|
||||
|
||||
class Buffer
|
||||
class ShaderBuffer
|
||||
{
|
||||
public:
|
||||
Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType);
|
||||
virtual ~Buffer();
|
||||
ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType);
|
||||
virtual ~ShaderBuffer();
|
||||
VkBuffer getHandle() const
|
||||
{
|
||||
return buffers[currentBuffer].buffer;
|
||||
@@ -108,9 +109,9 @@ protected:
|
||||
virtual VkAccessFlags getSourceAccessMask() = 0;
|
||||
virtual VkAccessFlags getDestAccessMask() = 0;
|
||||
};
|
||||
DEFINE_REF(Buffer);
|
||||
DEFINE_REF(ShaderBuffer);
|
||||
|
||||
class UniformBuffer : public Buffer, public Gfx::UniformBuffer
|
||||
class UniformBuffer : public Gfx::UniformBuffer, public ShaderBuffer
|
||||
{
|
||||
public:
|
||||
UniformBuffer(PGraphics graphics, const BulkResourceData &resourceData);
|
||||
@@ -126,7 +127,7 @@ protected:
|
||||
};
|
||||
DEFINE_REF(UniformBuffer);
|
||||
|
||||
class StructuredBuffer : public Buffer, public Gfx::StructuredBuffer
|
||||
class StructuredBuffer : public Gfx::StructuredBuffer, public ShaderBuffer
|
||||
{
|
||||
public:
|
||||
StructuredBuffer(PGraphics graphics, const BulkResourceData &resourceData);
|
||||
@@ -142,7 +143,7 @@ protected:
|
||||
};
|
||||
DEFINE_REF(StructuredBuffer);
|
||||
|
||||
class VertexBuffer : public Buffer, public Gfx::VertexBuffer
|
||||
class VertexBuffer : public Gfx::VertexBuffer, public ShaderBuffer
|
||||
{
|
||||
public:
|
||||
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData);
|
||||
@@ -158,7 +159,7 @@ protected:
|
||||
};
|
||||
DEFINE_REF(VertexBuffer);
|
||||
|
||||
class IndexBuffer : public Buffer, public Gfx::IndexBuffer
|
||||
class IndexBuffer : public Gfx::IndexBuffer, public ShaderBuffer
|
||||
{
|
||||
public:
|
||||
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData);
|
||||
@@ -249,7 +250,7 @@ protected:
|
||||
};
|
||||
DEFINE_REF(TextureBase);
|
||||
|
||||
class Texture2D : public TextureBase, public Gfx::Texture2D
|
||||
class Texture2D : public Gfx::Texture2D, public TextureBase
|
||||
{
|
||||
public:
|
||||
Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
|
||||
|
||||
@@ -242,7 +242,6 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
|
||||
0
|
||||
);
|
||||
|
||||
|
||||
createInfo.pStages = stageInfos;
|
||||
createInfo.pVertexInputState = &vertexInput;
|
||||
createInfo.pInputAssemblyState = &assemblyInfo;
|
||||
|
||||
@@ -55,7 +55,6 @@ void Shader::create(const ShaderCreateInfo& createInfo)
|
||||
int targetIndex = spAddCodeGenTarget(request, SLANG_SPIRV);
|
||||
spSetTargetProfile(request, targetIndex, spFindProfile(session, "glsl_vk"));
|
||||
spSetDumpIntermediates(request, true);
|
||||
|
||||
int translationUnitIndex = spAddTranslationUnit(request, SLANG_SOURCE_LANGUAGE_SLANG, "");
|
||||
|
||||
for(auto code : createInfo.shaderCode)
|
||||
@@ -67,15 +66,20 @@ void Shader::create(const ShaderCreateInfo& createInfo)
|
||||
code.data()
|
||||
);
|
||||
}
|
||||
for(auto define : createInfo.defines)
|
||||
{
|
||||
spAddPreprocessorDefine(request, define.key, define.value);
|
||||
}
|
||||
spAddSearchPath(request, "shaders/lib/");
|
||||
spAddSearchPath(request, "shaders/generated/");
|
||||
|
||||
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;
|
||||
char const* diagnostics = spGetDiagnosticOutput(request);
|
||||
std::cout << diagnostics << std::endl;
|
||||
}
|
||||
|
||||
ShaderReflection* reflection = slang::ShaderReflection::get(request);
|
||||
|
||||
@@ -154,12 +154,12 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
|
||||
TextureHandle::~TextureHandle()
|
||||
{
|
||||
auto &deletionQueue = graphics->getDeletionQueue();
|
||||
auto fence = graphics->getQueueCommands(currentOwner)->getCommands()->getFence();
|
||||
auto cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
|
||||
VkDevice device = graphics->getDevice();
|
||||
VkImageView view = defaultView;
|
||||
VkImage img = image;
|
||||
deletionQueue.addPendingDelete(fence, [device, view]() { vkDestroyImageView(device, view, nullptr); });
|
||||
deletionQueue.addPendingDelete(fence, [device, img]() { vkDestroyImage(device, img, nullptr); });
|
||||
deletionQueue.addPendingDelete(cmdBuffer, [device, view]() { vkDestroyImageView(device, view, nullptr); });
|
||||
deletionQueue.addPendingDelete(cmdBuffer, [device, img]() { vkDestroyImage(device, img, nullptr); });
|
||||
}
|
||||
|
||||
void TextureHandle::changeLayout(VkImageLayout newLayout)
|
||||
@@ -243,7 +243,7 @@ void TextureBase::changeLayout(VkImageLayout newLayout)
|
||||
}
|
||||
|
||||
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
|
||||
: Gfx::Texture2D(graphics, createInfo.resourceData.owner)
|
||||
: Gfx::Texture2D(graphics->getFamilyMapping(), createInfo.resourceData.owner)
|
||||
{
|
||||
textureHandle = new TextureHandle(graphics, createInfo.bArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
|
||||
createInfo, existingImage);
|
||||
|
||||
@@ -42,6 +42,14 @@ void Seele::WindowManager::beginFrame()
|
||||
}
|
||||
}
|
||||
|
||||
void WindowManager::render()
|
||||
{
|
||||
for(auto window : windows)
|
||||
{
|
||||
window->render();
|
||||
}
|
||||
}
|
||||
|
||||
void Seele::WindowManager::endFrame()
|
||||
{
|
||||
for (auto window : windows)
|
||||
|
||||
@@ -13,6 +13,7 @@ public:
|
||||
~WindowManager();
|
||||
PWindow addWindow(const WindowCreateInfo &createInfo);
|
||||
void beginFrame();
|
||||
void render();
|
||||
void endFrame();
|
||||
static Gfx::PGraphics getGraphics()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user