Implementing ECS SystemBase and updating slang
This commit is contained in:
@@ -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