Implementing ECS SystemBase and updating slang

This commit is contained in:
Dynamitos
2022-11-15 12:19:11 +01:00
parent 05bc31a2b4
commit f635ee2100
106 changed files with 1083 additions and 1675 deletions
+3 -3
View File
@@ -18,10 +18,10 @@ PVertexBuffer Graphics::getNullVertexBuffer()
{
VertexBufferCreateInfo createInfo;
createInfo.numVertices = 1;
createInfo.vertexSize = sizeof(Vector4);
Vector4 data = Vector4(1, 1, 1, 1);
createInfo.vertexSize = sizeof(Math::Vector4);
Math::Vector4 data = Math::Vector4(1, 1, 1, 1);
createInfo.resourceData.data = reinterpret_cast<uint8*>(&data);
createInfo.resourceData.size = sizeof(Vector4);
createInfo.resourceData.size = sizeof(Math::Vector4);
nullVertexBuffer = createVertexBuffer(createInfo);
}
return nullVertexBuffer;
+4 -2
View File
@@ -50,7 +50,8 @@ struct ViewportCreateInfo
// doesnt own the data, only proxy it
struct BulkResourceData
{
uint32 size = 0;
uint64 size = 0;
uint64 offset = 0;
uint8 *data = nullptr;
Gfx::QueueType owner = Gfx::QueueType::GRAPHICS;
};
@@ -111,8 +112,9 @@ struct StructuredBufferCreateInfo
};
struct ShaderCreateInfo
{
std::string mainModule;
//It's possible to input multiple source files for materials or vertexFactories
Array<std::string> shaderCode;
Array<std::string> additionalModules;
std::string name; // Debug info
std::string entryPoint;
Array<const char*> typeParameter;
+130 -6
View File
@@ -2,6 +2,7 @@
#include "Graphics.h"
#include "RenderPass/DepthPrepass.h"
#include "RenderPass/BasePass.h"
#include "Material/MaterialAsset.h"
using namespace Seele;
using namespace Seele::Gfx;
@@ -11,9 +12,9 @@ std::string getShaderNameFromRenderPassType(Gfx::RenderPassType type)
switch (type)
{
case Gfx::RenderPassType::DepthPrepass:
return "DepthPrepass.slang";
return "DepthPrepass";
case Gfx::RenderPassType::BasePass:
return "ForwardPlus.slang";
return "ForwardPlus";
default:
return "";
}
@@ -64,8 +65,6 @@ ShaderCollection& ShaderMap::createShaders(
ShaderCreateInfo createInfo;
createInfo.entryPoint = "vertexMain";
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";
modifyRenderPassMacros(renderPass, createInfo.defines);
@@ -73,7 +72,9 @@ ShaderCollection& ShaderMap::createShaders(
std::ifstream codeStream("./shaders/" + getShaderNameFromRenderPassType(renderPass));
createInfo.shaderCode.add(std::string(std::istreambuf_iterator<char>{codeStream}, {}));
createInfo.mainModule = getShaderNameFromRenderPassType(renderPass);
createInfo.additionalModules.add(vertexInput->getShaderFilename());
createInfo.additionalModules.add(material->getName());
collection.vertexShader = graphics->createVertexShader(createInfo);
@@ -227,7 +228,7 @@ VertexBuffer::VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint3
VertexBuffer::~VertexBuffer()
{
}
IndexBuffer::IndexBuffer(QueueFamilyMapping mapping, uint32 size, Gfx::SeIndexType indexType, QueueType startQueueType)
IndexBuffer::IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType indexType, QueueType startQueueType)
: Buffer(mapping, startQueueType)
, indexType(indexType)
{
@@ -264,6 +265,129 @@ const Array<VertexElement> VertexStream::getVertexDescriptions() const
{
return vertexDescription;
}
VertexDataManager::VertexDataManager(PGraphics graphics)
: currentSize(8 * 1024 * 1024)
, inUse(0)
, graphics(graphics)
{
VertexBufferCreateInfo defaultInfo = {
.resourceData = {
.size = currentSize,
.data = nullptr,
}
};
buffer = graphics->createVertexBuffer(defaultInfo);
}
VertexDataManager::~VertexDataManager()
{
}
VertexDataAllocation VertexDataManager::createVertexBuffer(const VertexBufferCreateInfo& vbInfo)
{
VertexDataAllocation data = allocateData(vbInfo.resourceData.size);
buffer->updateRegion(BulkResourceData{
.size = data.size,
.offset = data.offset,
.data = vbInfo.resourceData.data
});
activeAllocations[data.offset] = data;
return data;
}
void VertexDataManager::freeAllocation(VertexDataAllocation alloc)
{
uint64 lowerBound = alloc.offset;
uint64 upperBound = alloc.offset + alloc.size;
bool joinedLower = false;
uint64 lowerOffset = 0;
//Join lower bound
for (auto& [offset, freeAlloc] : freeRanges)
{
if (freeAlloc.offset <= lowerBound
&& freeAlloc.offset + freeAlloc.size >= upperBound)
{
// allocation is already in a free region
return;
}
if (freeAlloc.offset + freeAlloc.size == lowerBound)
{
//extend freeAlloc by the allocatedSize
freeAlloc.size += alloc.size;
joinedLower = true;
lowerOffset = freeAlloc.offset;
break;
}
}
//Join upper bound
auto foundAlloc = freeRanges.find(upperBound);
if (foundAlloc != freeRanges.end())
{
// There is a free allocation ending where the new free one ends
if (joinedLower)
{
// extend allocHandle by another foundAlloc->allocatedSize bytes
freeRanges[lowerOffset].size += foundAlloc->value.size;
freeRanges.erase(upperBound);
}
else
{
// set foundAlloc back by size amount
freeRanges[upperBound].offset -= alloc.size;
freeRanges[upperBound].size += alloc.size;
// place back at correct offset
freeRanges[freeRanges[upperBound].offset] = freeRanges[upperBound];
// remove from offset map since key changes
freeRanges.erase(upperBound);
}
}
else
{
// No matching upper bound found
if(!joinedLower)
{
// Lower bound also not joined, create new range
freeRanges[alloc.offset] = alloc;
}
}
activeAllocations.erase(alloc.offset);
inUse -= alloc.size;
}
VertexDataAllocation VertexDataManager::allocateData(uint64 size)
{
for (auto& [offset, freeAllocation] : freeRanges)
{
assert(offset == freeAllocation.offset);
if (freeAllocation.size == size)
{
activeAllocations[offset] = freeAllocation;
freeRanges.erase(offset);
inUse += size;
return freeAllocation;
}
else if (size < freeAllocation.size)
{
freeAllocation.size -= size;
freeAllocation.offset += size;
VertexDataAllocation subAlloc = VertexDataAllocation(size, offset);
activeAllocations[offset] = subAlloc;
freeRanges[freeAllocation.offset] = freeAllocation;
freeRanges.erase(offset);
inUse += size;
return subAlloc;
}
}
throw std::logic_error("TODO: expand buffer");
}
VertexDeclaration::VertexDeclaration()
{
}
+36 -4
View File
@@ -3,7 +3,10 @@
#include "Containers/Array.h"
#include "Containers/List.h"
#include "GraphicsInitializer.h"
#pragma warning(push)
#pragma warning(disable: 4701)
#include <boost/crc.hpp>
#pragma warning(pop)
#include <functional>
@@ -372,6 +375,8 @@ public:
return vertexSize;
}
virtual void updateRegion(BulkResourceData update) = 0;
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
@@ -385,9 +390,9 @@ DEFINE_REF(VertexBuffer)
class IndexBuffer : public Buffer
{
public:
IndexBuffer(QueueFamilyMapping mapping, uint32 size, Gfx::SeIndexType index, QueueType startQueueType);
IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType index, QueueType startQueueType);
virtual ~IndexBuffer();
constexpr uint32 getNumIndices() const
constexpr uint64 getNumIndices() const
{
return numIndices;
}
@@ -402,7 +407,7 @@ protected:
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
Gfx::SeIndexType indexType;
uint32 numIndices;
uint64 numIndices;
};
DEFINE_REF(IndexBuffer)
@@ -442,7 +447,6 @@ protected:
uint32 stride;
};
DEFINE_REF(StructuredBuffer)
class VertexStream
{
public:
@@ -459,6 +463,34 @@ public:
uint8 instanced;
};
DEFINE_REF(VertexStream)
struct VertexDataAllocation
{
uint64 size;
uint64 offset;
};
class VertexDataManager
{
public:
VertexDataManager(PGraphics graphics);
virtual ~VertexDataManager();
VertexDataAllocation createVertexBuffer(const VertexBufferCreateInfo& vbInfo);
void freeAllocation(VertexDataAllocation alloc);
PVertexBuffer getVertexBuffer() const { return buffer; }
private:
VertexDataAllocation allocateData(uint64 size);
Map<uint64, VertexDataAllocation> freeRanges;
Map<uint64, VertexDataAllocation> activeAllocations;
uint64 currentSize;
uint64 inUse;
PVertexBuffer buffer;
PGraphics graphics;
};
DEFINE_REF(VertexDataManager)
class VertexDeclaration
{
public:
+1 -3
View File
@@ -34,7 +34,7 @@ public:
};
struct MeshBatch
{
std::vector<MeshBatchElement> elements;
Array<MeshBatchElement> elements;
uint8 useReverseCulling : 1;
uint8 isBackfaceCullingDisabled : 1;
@@ -73,10 +73,8 @@ struct MeshBatch
MeshBatch& operator=(const MeshBatch& other) = default;
MeshBatch& operator=(MeshBatch&& other) = default;
};
DECLARE_REF(PrimitiveComponent)
struct StaticMeshBatch : public MeshBatch
{
uint32 index;
PPrimitiveComponent primitiveComponent;
};
} // namespace Seele
+7 -6
View File
@@ -1,10 +1,11 @@
#include "BasePass.h"
#include "Graphics/Graphics.h"
#include "Window/Window.h"
#include "Scene/Components/CameraComponent.h"
#include "Scene/Component/Camera.h"
#include "Scene/Actor/CameraActor.h"
#include "Math/Vector.h"
#include "RenderGraph.h"
#include "Material/MaterialAsset.h"
using namespace Seele;
@@ -73,7 +74,7 @@ BasePass::BasePass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActo
: RenderPass(graphics, viewport)
, processor(new BasePassMeshProcessor(viewport, graphics, false))
, descriptorSets(4)
, source(source->getCameraComponent())
, source(source)
{
UniformBufferCreateInfo uniformInitializer;
basePassLayout = graphics->createPipelineLayout();
@@ -120,11 +121,11 @@ void BasePass::beginFrame()
primitiveLayout->reset();
BulkResourceData uniformUpdate;
viewParams.viewMatrix = source->getViewMatrix();
viewParams.projectionMatrix = source->getProjectionMatrix();
viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0);
viewParams.viewMatrix = source->getCameraComponent().getViewMatrix();
viewParams.projectionMatrix = source->getCameraComponent().getProjectionMatrix();
viewParams.cameraPosition = Math::Vector4(source->getCameraComponent().getCameraPosition(), 0);
viewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix);
viewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
viewParams.screenDimensions = Math::Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
uniformUpdate.size = sizeof(ViewParameter);
uniformUpdate.data = (uint8*)&viewParams;
viewParamBuffer->updateContents(uniformUpdate);
+2 -3
View File
@@ -27,10 +27,9 @@ private:
};
DEFINE_REF(BasePassMeshProcessor)
DECLARE_REF(CameraActor)
DECLARE_REF(CameraComponent)
struct BasePassData
{
std::vector<StaticMeshBatch> staticDrawList;
Array<StaticMeshBatch> staticDrawList;
};
class BasePass : public RenderPass<BasePassData>
{
@@ -49,7 +48,7 @@ private:
UPBasePassMeshProcessor processor;
Array<Gfx::PDescriptorSet> descriptorSets;
PCameraComponent source;
PCameraActor source;
Gfx::PPipelineLayout basePassLayout;
// Set 0: Light environment
static constexpr uint32 INDEX_LIGHT_ENV = 0;
@@ -1,10 +1,11 @@
#include "DepthPrepass.h"
#include "Graphics/Graphics.h"
#include "Window/Window.h"
#include "Scene/Components/CameraComponent.h"
#include "Scene/Component/Camera.h"
#include "Scene/Actor/CameraActor.h"
#include "Math/Vector.h"
#include "RenderGraph.h"
#include "Material/MaterialAsset.h"
using namespace Seele;
@@ -72,7 +73,7 @@ DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCa
: RenderPass(graphics, viewport)
, processor(new DepthPrepassMeshProcessor(viewport, graphics))
, descriptorSets(3)
, source(source->getCameraComponent())
, source(source)
{
UniformBufferCreateInfo uniformInitializer;
@@ -103,11 +104,11 @@ void DepthPrepass::beginFrame()
primitiveLayout->reset();
BulkResourceData uniformUpdate;
viewParams.viewMatrix = source->getViewMatrix();
viewParams.projectionMatrix = source->getProjectionMatrix();
viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0);
viewParams.viewMatrix = source->getCameraComponent().getViewMatrix();
viewParams.projectionMatrix = source->getCameraComponent().getProjectionMatrix();
viewParams.cameraPosition = Math::Vector4(source->getCameraComponent().getCameraPosition(), 0);
viewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix);
viewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
viewParams.screenDimensions = Math::Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
uniformUpdate.size = sizeof(ViewParameter);
uniformUpdate.data = (uint8*)&viewParams;
viewParamBuffer->updateContents(uniformUpdate);
@@ -24,10 +24,9 @@ private:
};
DEFINE_REF(DepthPrepassMeshProcessor)
DECLARE_REF(CameraActor)
DECLARE_REF(CameraComponent)
struct DepthPrepassData
{
std::vector<StaticMeshBatch> staticDrawList;
Array<StaticMeshBatch> staticDrawList;
};
class DepthPrepass : public RenderPass<DepthPrepassData>
{
@@ -46,7 +45,7 @@ private:
UPDepthPrepassMeshProcessor processor;
Array<Gfx::PDescriptorSet> descriptorSets;
PCameraComponent source;
PCameraActor source;
Gfx::PPipelineLayout depthPrepassLayout;
// Set 0: viewParameter
static constexpr uint32 INDEX_VIEW_PARAMS = 0;
@@ -2,14 +2,14 @@
#include "Graphics/Graphics.h"
#include "Scene/Scene.h"
#include "Scene/Actor/CameraActor.h"
#include "Scene/Components/CameraComponent.h"
#include "Scene/Component/Camera.h"
#include "RenderGraph.h"
using namespace Seele;
LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor camera)
: RenderPass(graphics, viewport)
, source(camera->getCameraComponent())
, source(camera)
{
}
@@ -24,11 +24,11 @@ void LightCullingPass::beginFrame()
uint32_t viewportHeight = viewport->getSizeY();
BulkResourceData uniformUpdate;
viewParams.viewMatrix = source->getViewMatrix();
viewParams.projectionMatrix = source->getProjectionMatrix();
viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0);
viewParams.viewMatrix = source->getCameraComponent().getViewMatrix();
viewParams.projectionMatrix = source->getCameraComponent().getProjectionMatrix();
viewParams.cameraPosition = Math::Vector4(source->getCameraComponent().getCameraPosition(), 0);
viewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix);
viewParams.screenDimensions = Vector2(static_cast<float>(viewportWidth), static_cast<float>(viewportHeight));
viewParams.screenDimensions = Math::Vector2(static_cast<float>(viewportWidth), static_cast<float>(viewportHeight));
uniformUpdate.size = sizeof(ViewParameter);
uniformUpdate.data = (uint8*)&viewParams;
viewParamsBuffer->updateContents(uniformUpdate);
@@ -162,13 +162,7 @@ void LightCullingPass::publishOutputs()
ShaderCreateInfo createInfo;
createInfo.name = "Culling";
std::ifstream codeStream("./shaders/LightCulling.slang", 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()));
createInfo.mainModule = "LightCulling";
createInfo.entryPoint = "cullLights";
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
createInfo.defines["INDEX_LIGHT_ENV"] = "1";
@@ -269,10 +263,10 @@ void LightCullingPass::setupFrustums()
glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1));
viewParams = {
.viewMatrix = source->getViewMatrix(),
.projectionMatrix = source->getProjectionMatrix(),
.inverseProjectionMatrix = glm::inverse(source->getProjectionMatrix()),
.cameraPosition = Vector4(source->getCameraPosition(), 0),
.viewMatrix = source->getCameraComponent().getViewMatrix(),
.projectionMatrix = source->getCameraComponent().getProjectionMatrix(),
.inverseProjectionMatrix = glm::inverse(source->getCameraComponent().getProjectionMatrix()),
.cameraPosition = Math::Vector4(source->getTransform().getPosition(), 0),
.screenDimensions = glm::vec2(viewportWidth, viewportHeight),
};
dispatchParams.numThreads = numThreads;
@@ -288,13 +282,7 @@ void LightCullingPass::setupFrustums()
ShaderCreateInfo createInfo;
createInfo.name = "Frustum";
std::ifstream codeStream("./shaders/ComputeFrustums.slang", 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()));
createInfo.mainModule = "ComputeFrustums";
createInfo.entryPoint = "computeFrustums";
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
frustumShader = graphics->createComputeShader(createInfo);
@@ -6,7 +6,6 @@
namespace Seele
{
DECLARE_REF(CameraActor)
DECLARE_REF(CameraComponent)
DECLARE_REF(Scene)
DECLARE_REF(Viewport)
struct LightCullingPassData
@@ -37,7 +36,7 @@ private:
} dispatchParams;
struct Plane
{
Vector n;
Math::Vector n;
float d;
};
struct Frustum
@@ -72,7 +71,7 @@ private:
Gfx::PComputeShader cullingShader;
Gfx::PPipelineLayout cullingLayout;
Gfx::PComputePipeline cullingPipeline;
PCameraComponent source;
PCameraActor source;
};
DEFINE_REF(LightCullingPass)
} // namespace Seele
+7 -6
View File
@@ -26,15 +26,16 @@ public:
virtual void endFrame() = 0;
virtual void publishOutputs() = 0;
virtual void createRenderPass() = 0;
void setResources(PRenderGraphResources resources) { this->resources = resources; }
void setResources(PRenderGraphResources _resources) { resources = _resources; }
protected:
struct ViewParameter
{
Matrix4 viewMatrix;
Matrix4 projectionMatrix;
Matrix4 inverseProjectionMatrix;
Vector4 cameraPosition;
Vector2 screenDimensions;
Math::Matrix4 viewMatrix;
Math::Matrix4 projectionMatrix;
Math::Matrix4 inverseProjectionMatrix;
Math::Vector4 cameraPosition;
Math::Vector2 screenDimensions;
Math::Vector2 pad0;
} viewParams;
PRenderGraphResources resources;
RenderPassDataType passData;
+16 -22
View File
@@ -20,16 +20,16 @@ void TextPass::beginFrame()
{
for(TextRender& render : passData.texts)
{
FontData& fontData = getFontData(render.font);
TextResources& resources = textResources[render.font].add();
FontData& fd = getFontData(render.font);
TextResources& res = textResources[render.font].add();
Array<GlyphInstanceData> instanceData;
float x = render.position.x;
float y = render.position.y;
for(uint32 c : render.text)
{
const GlyphData& glyph = fontData.glyphDataSet[fontData.characterToGlyphIndex[c]];
Vector2 bearing = glyph.bearing;
Vector2 size = glyph.size;
const GlyphData& glyph = fd.glyphDataSet[fd.characterToGlyphIndex[c]];
Math::Vector2 bearing = glyph.bearing;
Math::Vector2 size = glyph.size;
float xpos = x + bearing.x * render.scale;
float ypos = y - (size.y - bearing.y) * render.scale;
@@ -37,9 +37,9 @@ void TextPass::beginFrame()
float h = size.y * render.scale;
instanceData.add(GlyphInstanceData{
.position = Vector2(xpos, ypos),
.widthHeight = Vector2(w, h),
.glyphIndex = fontData.characterToGlyphIndex[c],
.position = Math::Vector2(xpos, ypos),
.widthHeight = Math::Vector2(w, h),
.glyphIndex = fd.characterToGlyphIndex[c],
});
x += (glyph.advance >> 6) * render.scale;
}
@@ -51,11 +51,11 @@ void TextPass::beginFrame()
.vertexSize = sizeof(GlyphInstanceData),
.numVertices = static_cast<uint32>(instanceData.size()),
};
resources.vertexBuffer = graphics->createVertexBuffer(vbInfo);
res.vertexBuffer = graphics->createVertexBuffer(vbInfo);
resources.textureArraySet = fontData.textureArraySet;
res.textureArraySet = fd.textureArraySet;
resources.textData = {
res.textData = {
.textColor = render.textColor,
.scale = render.scale,
};
@@ -67,12 +67,12 @@ void TextPass::render()
{
graphics->beginRenderPass(renderPass);
Array<Gfx::PRenderCommand> commands;
for(const auto& [fontAsset, resources] : textResources)
for(const auto& [fontAsset, res] : textResources)
{
Gfx::PRenderCommand command = graphics->createRenderCommand("TextPassCommand");
command->setViewport(viewport);
command->bindPipeline(pipeline);
for(const auto& resource : resources)
for(const auto& resource : res)
{
command->bindDescriptor({generalSet, resource.textureArraySet});
command->bindVertexBuffer({VertexInputStream(0, 0, resource.vertexBuffer)});
@@ -100,14 +100,8 @@ void TextPass::publishOutputs()
void TextPass::createRenderPass()
{
depthAttachment = resources->requestRenderTarget("UIPASS_DEPTH");
std::ifstream codeStream("./shaders/TextPass.slang", std::ios::ate);
auto fileSize = codeStream.tellg();
codeStream.seekg(0);
Array<char> buffer(static_cast<uint32>(fileSize));
codeStream.read(buffer.data(), fileSize);
ShaderCreateInfo createInfo;
createInfo.shaderCode.add(std::string(buffer.data()));
createInfo.mainModule = "TextPass";
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
createInfo.name = "TextVertex";
createInfo.entryPoint = "vertexMain";
@@ -152,10 +146,10 @@ void TextPass::createRenderPass()
textureArrayLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 256, Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT);
textureArrayLayout->create();
Matrix4 projectionMatrix = glm::ortho(0.f, (float)viewport->getSizeX(), 0.f, (float)viewport->getSizeY());
Math::Matrix4 projectionMatrix = glm::ortho(0.f, (float)viewport->getSizeX(), 0.f, (float)viewport->getSizeY());
projectionBuffer = graphics->createUniformBuffer({
.resourceData = {
.size = sizeof(Matrix4),
.size = sizeof(Math::Matrix4),
.data = (uint8*)&projectionMatrix,
},
.bDynamic = false,
+7 -7
View File
@@ -13,8 +13,8 @@ struct TextRender
{
std::string text;
PFontAsset font;
Vector4 textColor;
Vector2 position;
Math::Vector4 textColor;
Math::Vector2 position;
float scale;
};
struct TextPassData
@@ -35,19 +35,19 @@ public:
private:
struct GlyphData
{
Vector2 bearing;
Vector2 size;
Math::Vector2 bearing;
Math::Vector2 size;
uint32 advance;
};
struct GlyphInstanceData
{
Vector2 position;
Vector2 widthHeight;
Math::Vector2 position;
Math::Vector2 widthHeight;
uint32 glyphIndex;
};
struct TextData
{
Vector4 textColor;
Math::Vector4 textColor;
float scale;
};
struct FontData
+5 -11
View File
@@ -26,7 +26,7 @@ void UIPass::beginFrame()
.numVertices = (uint32)passData.renderElements.size(),
};
elementBuffer = graphics->createVertexBuffer(info);
uint32 numTextures = passData.usedTextures.size();
uint32 numTextures = static_cast<uint32>(passData.usedTextures.size());
numTexturesBuffer->updateContents({
.size = sizeof(uint32),
.data = (uint8*)&numTextures,
@@ -45,7 +45,7 @@ void UIPass::render()
command->bindPipeline(pipeline);
command->bindVertexBuffer({VertexInputStream(0, 0, elementBuffer)});
command->bindDescriptor(descriptorSet);
command->draw(4, passData.renderElements.size(), 0, 0);
command->draw(4, static_cast<uint32>(passData.renderElements.size()), 0, 0);
graphics->executeCommands(Array<Gfx::PRenderCommand>({command}));
graphics->endRenderPass();
//co_return;
@@ -76,14 +76,8 @@ void UIPass::publishOutputs()
void UIPass::createRenderPass()
{
std::ifstream codeStream("./shaders/UIPass.slang", std::ios::ate);
auto fileSize = codeStream.tellg();
codeStream.seekg(0);
Array<char> buffer(static_cast<uint32>(fileSize));
codeStream.read(buffer.data(), fileSize);
ShaderCreateInfo createInfo;
createInfo.shaderCode.add(std::string(buffer.data()));
createInfo.mainModule = "UIPass";
createInfo.name = "UIVertex";
createInfo.entryPoint = "vertexMain";
vertexShader = graphics->createVertexShader(createInfo);
@@ -141,10 +135,10 @@ void UIPass::createRenderPass()
descriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 256, Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT | Gfx::SE_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT);
descriptorLayout->create();
Matrix4 projectionMatrix = glm::ortho(0, 1, 1, 0);
Math::Matrix4 projectionMatrix = glm::ortho(0, 1, 1, 0);
UniformBufferCreateInfo info = {
.resourceData = {
.size = sizeof(Matrix4),
.size = sizeof(Math::Matrix4),
.data = (uint8*)&projectionMatrix,
},
.bDynamic = false,
@@ -54,16 +54,16 @@ void StaticMeshVertexInput::init(Gfx::PGraphics graphics)
{
elements.add(accessStreamComponent(
data.textureCoordinates[coordinateIndex],
baseTexCoordAttribute + coordinateIndex
static_cast<uint8>(baseTexCoordAttribute + coordinateIndex)
));
}
}
initDeclaration(graphics, elements);
}
void StaticMeshVertexInput::setData(StaticMeshDataType&& data)
void StaticMeshVertexInput::setData(StaticMeshDataType&& _data)
{
this->data = std::move(data);
data = std::move(_data);
}
IMPLEMENT_VERTEX_INPUT_TYPE(StaticMeshVertexInput, "StaticMeshVertexInput")
+9 -7
View File
@@ -43,7 +43,7 @@ const char* VertexInputType::getName()
return name;
}
const char* VertexInputType::getShaderFilename()
std::string VertexInputType::getShaderFilename()
{
return shaderFilename;
}
@@ -90,20 +90,22 @@ Gfx::VertexElement VertexShaderInput::accessStreamComponent(const VertexStreamCo
{
VertexStream vertexStream;
vertexStream.vertexBuffer = component.vertexBuffer;
vertexStream.stride = component.stride;
vertexStream.offset = component.offset;
assert(component.stride < UINT8_MAX && component.offset < UINT8_MAX && component.offset < UINT8_MAX);
vertexStream.stride = static_cast<uint8>(component.stride);
vertexStream.offset = static_cast<uint8>(component.offset);
return Gfx::VertexElement((uint8)streams.indexOf(streams.addUnique(vertexStream)), component.offset, component.type, attributeIndex, vertexStream.stride);
return Gfx::VertexElement((uint8)streams.indexOf(streams.addUnique(vertexStream)), static_cast<uint8>(component.offset), component.type, attributeIndex, vertexStream.stride);
}
Gfx::VertexElement VertexShaderInput::accessPositionStreamComponent(const VertexStreamComponent& component, uint8 attributeIndex)
{
VertexStream vertexStream;
vertexStream.vertexBuffer = component.vertexBuffer;
vertexStream.stride = component.stride;
vertexStream.offset = component.offset;
assert(component.stride < UINT8_MAX && component.offset < UINT8_MAX && component.offset < UINT8_MAX);
vertexStream.stride = static_cast<uint8>(component.stride);
vertexStream.offset = static_cast<uint8>(component.offset);
return Gfx::VertexElement((uint8)positionStreams.indexOf(positionStreams.addUnique(vertexStream)), component.offset, component.type, attributeIndex, vertexStream.stride);
return Gfx::VertexElement((uint8)positionStreams.indexOf(positionStreams.addUnique(vertexStream)), static_cast<uint8>(component.offset), component.type, attributeIndex, vertexStream.stride);
}
void VertexShaderInput::initDeclaration(Gfx::PGraphics graphics, Array<Gfx::VertexElement>& elements)
+1 -1
View File
@@ -91,7 +91,7 @@ public:
virtual ~VertexInputType();
const char* getName();
const char* getShaderFilename();
std::string getShaderFilename();
private:
const char* name;
const char* shaderFilename;
@@ -95,7 +95,7 @@ PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice
VkDeviceSize allocatedOffset = it.first;
PSubAllocation freeAllocation = it.second;
assert(allocatedOffset == freeAllocation->allocatedOffset);
VkDeviceSize alignedOffset = align(allocatedOffset, alignment);
VkDeviceSize alignedOffset = Math::align(allocatedOffset, alignment);
VkDeviceSize alignmentAdjustment = alignedOffset - allocatedOffset;
VkDeviceSize size = alignmentAdjustment + requestedSize;
if (freeAllocation->size == size)
@@ -171,6 +171,8 @@ void Allocation::markFree(SubAllocation *allocation)
allocHandle = foundAlloc->second;
allocHandle->allocatedOffset -= allocation->allocatedSize;
allocHandle->alignedOffset -= allocation->allocatedSize;
allocHandle->size += allocation->allocatedSize;
allocHandle->allocatedSize += allocation->allocatedSize;
// place back at correct offset
freeRanges[allocHandle->allocatedOffset] = allocHandle;
// remove from offset map since key changes
@@ -310,7 +312,7 @@ void StagingManager::clearPending()
{
}
PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageFlags usage, bool bCPURead)
PStagingBuffer StagingManager::allocateStagingBuffer(uint64 size, VkBufferUsageFlags usage, bool bCPURead)
{
std::scoped_lock l(lock);
for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it)
+3 -3
View File
@@ -191,7 +191,7 @@ public:
{
return allocation->getOffset();
}
uint32 getSize() const
uint64 getSize() const
{
return size;
}
@@ -203,7 +203,7 @@ public:
private:
PSubAllocation allocation;
VkBuffer buffer;
uint32 size;
uint64 size;
VkBufferUsageFlags usage;
uint8 bReadable;
friend class StagingManager;
@@ -215,7 +215,7 @@ class StagingManager
public:
StagingManager(PGraphics graphics, PAllocator allocator);
~StagingManager();
PStagingBuffer allocateStagingBuffer(uint32 size, VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, bool bCPURead = false);
PStagingBuffer allocateStagingBuffer(uint64 size, VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, bool bCPURead = false);
void releaseStagingBuffer(PStagingBuffer buffer);
void clearPending();
+22 -4
View File
@@ -9,6 +9,8 @@ using namespace Seele::Vulkan;
struct PendingBuffer
{
uint64 offset;
uint64 size;
PStagingBuffer stagingBuffer;
Gfx::QueueType prevQueue;
bool bWriteOnly;
@@ -16,7 +18,7 @@ struct PendingBuffer
static std::map<ShaderBuffer *, PendingBuffer> pendingBuffers;
ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic)
ShaderBuffer::ShaderBuffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic)
: graphics(graphics)
, currentBuffer(0)
, size(size)
@@ -63,7 +65,7 @@ ShaderBuffer::~ShaderBuffer()
{
PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
VkDevice device = graphics->getDevice();
auto deletionLambda = [cmdBuffer, device](VkBuffer buffer) -> void
auto deletionLambda = [cmdBuffer, device](VkBuffer) -> void
{
//co_await cmdBuffer->asyncWait();
//vkDestroyBuffer(device, buffer, nullptr);
@@ -169,6 +171,11 @@ void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineSta
}
void *ShaderBuffer::lock(bool bWriteOnly)
{
return lockRegion(0, size, bWriteOnly);
}
void *ShaderBuffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnly)
{
void *data = nullptr;
@@ -189,10 +196,12 @@ void *ShaderBuffer::lock(bool bWriteOnly)
PendingBuffer pending;
pending.bWriteOnly = bWriteOnly;
pending.prevQueue = owner;
pending.offset = regionOffset;
pending.size = regionSize;
if (bWriteOnly)
{
//requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(regionSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
data = stagingBuffer->getMappedPointer();
pending.stagingBuffer = stagingBuffer;
}
@@ -255,7 +264,8 @@ void ShaderBuffer::unlock()
VkBufferCopy region;
std::memset(&region, 0, sizeof(VkBufferCopy));
region.size = size;
region.size = pending.size;
region.dstOffset = pending.offset;
vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, &region);
graphics->getQueueCommands(owner)->submitCommands();
}
@@ -448,6 +458,14 @@ VertexBuffer::~VertexBuffer()
{
}
void VertexBuffer::updateRegion(BulkResourceData update)
{
void* data = lockRegion(update.offset, update.size);
std::memcpy(data, update.data, update.size);
unlock();
}
void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
{
Gfx::QueueOwnedResource::transferOwnership(newOwner);
@@ -302,7 +302,7 @@ void RenderCommand::pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStag
void RenderCommand::draw(const MeshBatchElement& data)
{
assert(threadId == std::this_thread::get_id());
vkCmdDrawIndexed(handle, data.indexBuffer->getNumIndices(), data.numInstances, data.minVertexIndex, data.baseVertexIndex, 0);
vkCmdDrawIndexed(handle, static_cast<uint32>(data.indexBuffer->getNumIndices()), data.numInstances, data.minVertexIndex, data.baseVertexIndex, 0);
}
void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance)
@@ -67,6 +67,7 @@ public:
virtual Gfx::PPipelineLayout createPipelineLayout(Gfx::PPipelineLayout baseLayout = nullptr) override;
virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) override;
protected:
Array<const char *> getRequiredExtensions();
void initInstance(GraphicsInitializer initInfo);
@@ -1390,7 +1390,7 @@ Gfx::SeCompareOp Seele::Vulkan::cast(const VkCompareOp &op)
VkClearValue Seele::Vulkan::cast(const Gfx::SeClearValue& clear)
{
VkClearValue result;
if(sizeof(clear) == sizeof(Gfx::SeClearColorValue))
if constexpr (sizeof(clear) == sizeof(Gfx::SeClearColorValue))
{
result.color.float32[0] = clear.color.float32[0];
result.color.float32[1] = clear.color.float32[1];
@@ -1408,7 +1408,7 @@ VkClearValue Seele::Vulkan::cast(const Gfx::SeClearValue& clear)
Gfx::SeClearValue Seele::Vulkan::cast(const VkClearValue& clear)
{
Gfx::SeClearValue result;
if(sizeof(clear) == sizeof(VkClearColorValue))
if constexpr (sizeof(clear) == sizeof(VkClearColorValue))
{
result.color.float32[0] = clear.color.float32[0];
result.color.float32[1] = clear.color.float32[1];
@@ -72,13 +72,13 @@ DEFINE_REF(VertexDeclaration)
class ShaderBuffer
{
public:
ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false);
ShaderBuffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false);
virtual ~ShaderBuffer();
VkBuffer getHandle() const
{
return buffers[currentBuffer].buffer;
}
uint32 getSize() const
uint64 getSize() const
{
return size;
}
@@ -88,6 +88,7 @@ public:
currentBuffer = (currentBuffer + 1) % numBuffers;
}
virtual void *lock(bool bWriteOnly = true);
virtual void *lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnly = true);
virtual void unlock();
protected:
@@ -98,7 +99,7 @@ protected:
};
PGraphics graphics;
uint32 currentBuffer;
uint32 size;
uint64 size;
Gfx::QueueType& owner;
BufferAllocation buffers[Gfx::numFramesBuffered];
uint32 numBuffers;
@@ -168,6 +169,8 @@ public:
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData);
virtual ~VertexBuffer();
virtual void updateRegion(BulkResourceData update) override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask();
+103 -58
View File
@@ -2,9 +2,9 @@
#include "VulkanGraphics.h"
#include "VulkanDescriptorSets.h"
#include "slang.h"
#include "slang-com-ptr.h"
#include "stdlib.h"
using namespace slang;
using namespace Seele;
using namespace Seele::Vulkan;
@@ -33,85 +33,130 @@ uint32 Seele::Vulkan::Shader::getShaderHash() const
return hash;
}
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(nullptr);
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, "");
for(auto code : createInfo.shaderCode)
thread_local Slang::ComPtr<slang::IGlobalSession> globalSession;
if(!globalSession)
{
spAddTranslationUnitSourceString(
request,
translationUnitIndex,
entryPointName.c_str(),
code.data()
);
slang::createGlobalSession(globalSession.writeRef());
}
slang::SessionDesc sessionDesc;
sessionDesc.flags = 0;
sessionDesc.defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR;
Array<slang::PreprocessorMacroDesc> macros;
for(auto define : createInfo.defines)
{
spAddPreprocessorDefine(request, define.key, define.value);
macros.add(slang::PreprocessorMacroDesc{
.name = define.key,
.value = define.value
});
}
spAddSearchPath(request, "shaders/lib/");
spAddSearchPath(request, "shaders/generated/");
sessionDesc.preprocessorMacroCount = macros.size();
sessionDesc.preprocessorMacros = macros.data();
slang::TargetDesc vulkan;
vulkan.profile = globalSession->findProfile("glsl_vk");
vulkan.format = SLANG_SPIRV;
sessionDesc.targetCount = 1;
sessionDesc.targets = &vulkan;
StaticArray<const char*, 3> searchPaths = {"shaders/", "shaders/lib/", "shaders/generated/"};
sessionDesc.searchPaths = searchPaths.data();
sessionDesc.searchPathCount = searchPaths.size();
spSetGlobalGenericArgs(request, (int)createInfo.typeParameter.size(), createInfo.typeParameter.data());
Slang::ComPtr<slang::ISession> session;
globalSession->createSession(sessionDesc, session.writeRef());
Slang::ComPtr<slang::IBlob> diagnostics;
Array<slang::IComponentType*> modules;
Slang::ComPtr<slang::IEntryPoint> entrypoint;
int entryPointIndex = spAddEntryPoint(request, translationUnitIndex, entryPointName.c_str(), getStageFromShaderType(type));
if(spCompile(request))
for (auto moduleName : createInfo.additionalModules)
{
char const* diagnostics = spGetDiagnosticOutput(request);
std::cout << "Compile error for shader " << createInfo.name << std::endl;
std::cout << diagnostics << std::endl;
std::cout << "Defines: " << std::endl;
for(auto define : createInfo.defines)
modules.add(session->loadModule(moduleName.c_str(), diagnostics.writeRef()));
if(diagnostics)
{
std::cout << define.key << ": " << define.value << std::endl;
std::cout << (const char*)diagnostics->getBufferPointer() << std::endl;
}
std::cout << "For shader code: " << std::endl;
for(auto code : createInfo.shaderCode)
{
std::cout << code << std::endl;
}
return;
}
size_t dataSize = 0;
const uint32* data = reinterpret_cast<const uint32*>(spGetEntryPointCode(request, entryPointIndex, &dataSize));
slang::IModule* mainModule = session->loadModule(createInfo.mainModule.c_str(), diagnostics.writeRef());
modules.add(mainModule);
if(diagnostics)
{
std::cout << (const char*)diagnostics->getBufferPointer() << std::endl;
}
mainModule->findEntryPointByName(createInfo.entryPoint.c_str(), entrypoint.writeRef());
modules.add(entrypoint);
slang::IComponentType* moduleComposition;
session->createCompositeComponentType(modules.data(), modules.size(), &moduleComposition, diagnostics.writeRef());
if(diagnostics)
{
std::cout << (const char*)diagnostics->getBufferPointer() << std::endl;
}
/*for(auto typeParam : createInfo.typeParameter)
{
Slang::ComPtr<slang::ITypeConformance> typeConformance;
session->createTypeConformanceComponentType(moduleComposition->getLayout()->findTypeByName(typeParam), moduleComposition->getLayout()->findTypeByName("IMaterial"), typeConformance.writeRef(), -1, diagnostics.writeRef());
modules.add(typeConformance);
if(diagnostics)
{
std::cout << (const char*)diagnostics->getBufferPointer() << std::endl;
}
}
Slang::ComPtr<slang::IComponentType> conformingModule;
session->createCompositeComponentType(modules.data(), modules.size(), conformingModule.writeRef(), diagnostics.writeRef());
*/
Slang::ComPtr<slang::IComponentType> linkedProgram;
moduleComposition->link(linkedProgram.writeRef(), diagnostics.writeRef());
if(diagnostics)
{
std::cout << (const char*)diagnostics->getBufferPointer() << std::endl;
}
slang::ProgramLayout* reflection = linkedProgram->getLayout(0, diagnostics.writeRef());
if(diagnostics)
{
std::cout << (const char*)diagnostics->getBufferPointer() << std::endl;
}
Array<slang::SpecializationArg> specialization;
for(auto typeArg : createInfo.typeParameter)
{
specialization.add(slang::SpecializationArg::fromType(reflection->findTypeByName(typeArg)));
}
Slang::ComPtr<slang::IComponentType> specializedComponent;
linkedProgram->specialize(specialization.data(), specialization.size(), specializedComponent.writeRef(), diagnostics.writeRef());
if(diagnostics)
{
std::cout << (const char*)diagnostics->getBufferPointer() << std::endl;
}
Slang::ComPtr<slang::IBlob> kernelBlob;
specializedComponent->getEntryPointCode(
0,
0,
kernelBlob.writeRef(),
diagnostics.writeRef()
);
if(diagnostics)
{
std::cout << (const char*)diagnostics->getBufferPointer() << std::endl;
}
VkShaderModuleCreateInfo moduleInfo;
moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
moduleInfo.pNext = nullptr;
moduleInfo.flags = 0;
moduleInfo.codeSize = dataSize;
moduleInfo.pCode = data;
moduleInfo.codeSize = kernelBlob->getBufferSize();
moduleInfo.pCode = (uint32_t*)kernelBlob->getBufferPointer();
VK_CHECK(vkCreateShaderModule(graphics->getDevice(), &moduleInfo, nullptr, &module));
boost::crc_32_type result;
result.process_bytes(entryPointName.data(), entryPointName.size());
result.process_bytes(data, dataSize);
result.process_bytes(kernelBlob->getBufferPointer(), kernelBlob->getBufferSize());
hash = result.checksum();
}