Implementing ECS SystemBase and updating slang
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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(®ion, 0, sizeof(VkBufferCopy));
|
||||
region.size = size;
|
||||
region.size = pending.size;
|
||||
region.dstOffset = pending.offset;
|
||||
vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion);
|
||||
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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
Reference in New Issue
Block a user