Basic mutability framework

This commit is contained in:
Dynamitos
2022-01-12 14:40:26 +01:00
parent b2718dde70
commit 6d48267ec2
72 changed files with 1781 additions and 1341 deletions
+1 -1
View File
@@ -56,7 +56,7 @@ public:
virtual PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) = 0;
virtual PDescriptorLayout createDescriptorLayout(const std::string& name = "") = 0;
virtual PPipelineLayout createPipelineLayout() = 0;
virtual PPipelineLayout createPipelineLayout(PPipelineLayout baseLayout = nullptr) = 0;
virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) = 0;
+1 -8
View File
@@ -22,20 +22,13 @@ struct GraphicsInitializer
GraphicsInitializer()
: applicationName("SeeleEngine")
, engineName("SeeleEngine")
, windowLayoutFile(nullptr)
, layers{"VK_LAYER_KHRONOS_validation", "VK_LAYER_LUNARG_monitor"}
, instanceExtensions{}
, deviceExtensions{"VK_KHR_swapchain"}
, windowHandle(nullptr)
{
}
GraphicsInitializer(const GraphicsInitializer &other)
: applicationName(other.applicationName)
, engineName(other.engineName)
, layers(other.layers)
, instanceExtensions(other.instanceExtensions)
, deviceExtensions(other.deviceExtensions)
{
}
};
struct WindowCreateInfo
{
+4 -3
View File
@@ -57,6 +57,7 @@ ShaderCollection& ShaderMap::createShaders(
VertexInputType* vertexInput,
bool /*bPositionOnly*/)
{
std::scoped_lock lock(shadersLock);
ShaderCollection& collection = shaders.add();
//collection.vertexDeclaration = bPositionOnly ? vertexInput->getPositionDeclaration() : vertexInput->getDeclaration();
@@ -107,7 +108,7 @@ void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorTyp
PDescriptorSet DescriptorLayout::allocateDescriptorSet()
{
std::unique_lock lock(allocatorLock);
std::scoped_lock lock(allocatorLock);
PDescriptorSet result;
allocator->allocateDescriptorSet(result);
return result;
@@ -115,7 +116,7 @@ PDescriptorSet DescriptorLayout::allocateDescriptorSet()
void DescriptorLayout::reset()
{
std::unique_lock lock(allocatorLock);
std::scoped_lock lock(allocatorLock);
allocator->reset();
}
@@ -270,7 +271,7 @@ static Map<uint32, PVertexDeclaration> vertexDeclarationCache;
PVertexDeclaration VertexDeclaration::createDeclaration(PGraphics graphics, const Array<VertexElement>& elementList)
{
std::unique_lock lock(vertexDeclarationLock);
std::scoped_lock lock(vertexDeclarationLock);
boost::crc_32_type result;
result.process_bytes(&elementList, sizeof(VertexElement) * elementList.size());
uint32 key = result.checksum();
+9 -1
View File
@@ -144,6 +144,7 @@ public:
VertexInputType* vertexInput,
bool bPositionOnly);
private:
std::mutex shadersLock;
Array<ShaderCollection> shaders;
};
DEFINE_REF(ShaderMap)
@@ -242,7 +243,14 @@ DEFINE_REF(DescriptorLayout)
class PipelineLayout
{
public:
PipelineLayout() {}
PipelineLayout(PPipelineLayout baseLayout)
{
if(baseLayout != nullptr)
{
descriptorSetLayouts = baseLayout->descriptorSetLayouts;
pushConstants = baseLayout->pushConstants;
}
}
virtual ~PipelineLayout() {}
virtual void create() = 0;
virtual void reset() = 0;
-5
View File
@@ -15,11 +15,6 @@ public:
PVertexShaderInput vertexInput;
PMaterialAsset referencedMaterial;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive&, const unsigned int)
{
}
};
DEFINE_REF(Mesh)
} // namespace Seele
+1
View File
@@ -24,5 +24,6 @@ MeshBatch::MeshBatch()
, topology(Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
, vertexInput(nullptr)
, material(nullptr)
, elements()
{
}
+5 -1
View File
@@ -34,7 +34,7 @@ public:
};
struct MeshBatch
{
Array<MeshBatchElement> elements;
std::vector<MeshBatchElement> elements;
uint8 useReverseCulling : 1;
uint8 isBackfaceCullingDisabled : 1;
@@ -68,6 +68,10 @@ struct MeshBatch
}
MeshBatch();
MeshBatch(const MeshBatch& other) = default;
MeshBatch(MeshBatch&& other) = default;
MeshBatch& operator=(const MeshBatch& other) = default;
MeshBatch& operator=(MeshBatch&& other) = default;
};
DECLARE_REF(PrimitiveComponent)
struct StaticMeshBatch : public MeshBatch
+6 -5
View File
@@ -20,11 +20,11 @@ BasePassMeshProcessor::~BasePassMeshProcessor()
{
}
void BasePassMeshProcessor::processMeshBatch(
Job BasePassMeshProcessor::processMeshBatch(
const MeshBatch& batch,
// const PPrimitiveComponent primitiveComponent,
const Gfx::PRenderPass& renderPass,
Gfx::PPipelineLayout pipelineLayout,
Gfx::PPipelineLayout baseLayout,
Gfx::PDescriptorLayout primitiveLayout,
Array<Gfx::PDescriptorSet> descriptorSets,
int32 /*staticMeshId*/)
@@ -40,6 +40,7 @@ void BasePassMeshProcessor::processMeshBatch(
Gfx::PRenderCommand renderCommand = graphics->createRenderCommand();
renderCommand->setViewport(target);
Gfx::PPipelineLayout pipelineLayout = graphics->createPipelineLayout(baseLayout);
pipelineLayout->addDescriptorLayout(BasePass::INDEX_MATERIAL, material->getDescriptorLayout());
pipelineLayout->create();
Gfx::PDescriptorSet materialSet = material->createDescriptorSet();
@@ -63,9 +64,9 @@ void BasePassMeshProcessor::processMeshBatch(
collection->fragmentShader,
false);
}
std::unique_lock lock(commandLock);
std::scoped_lock lock(commandLock);
renderCommands.add(renderCommand);
//co_return;
co_return;
}
BasePass::BasePass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source)
@@ -157,7 +158,7 @@ MainJob BasePass::render()
for (auto &&meshBatch : passData.staticDrawList)
{
//jobs.add(
processor->processMeshBatch(meshBatch, renderPass, basePassLayout, primitiveLayout, descriptorSets);
co_await processor->processMeshBatch(meshBatch, renderPass, basePassLayout, primitiveLayout, descriptorSets);
}
//co_await Job::all(jobs);
graphics->executeCommands(processor->getRenderCommands());
+2 -2
View File
@@ -11,7 +11,7 @@ public:
BasePassMeshProcessor(Gfx::PViewport viewport, Gfx::PGraphics graphics, uint8 translucentBasePass);
virtual ~BasePassMeshProcessor();
virtual void processMeshBatch(
virtual Job processMeshBatch(
const MeshBatch& batch,
// const PPrimitiveComponent primitiveComponent,
const Gfx::PRenderPass& renderPass,
@@ -30,7 +30,7 @@ DECLARE_REF(CameraActor)
DECLARE_REF(CameraComponent)
struct BasePassData
{
Array<StaticMeshBatch> staticDrawList;
std::vector<StaticMeshBatch> staticDrawList;
};
class BasePass : public RenderPass<BasePassData>
{
@@ -18,11 +18,11 @@ DepthPrepassMeshProcessor::~DepthPrepassMeshProcessor()
{
}
void DepthPrepassMeshProcessor::processMeshBatch(
Job DepthPrepassMeshProcessor::processMeshBatch(
const MeshBatch& batch,
// const PPrimitiveComponent primitiveComponent,
const Gfx::PRenderPass& renderPass,
Gfx::PPipelineLayout pipelineLayout,
Gfx::PPipelineLayout baseLayout,
Gfx::PDescriptorLayout primitiveLayout,
Array<Gfx::PDescriptorSet> descriptorSets,
int32 /*staticMeshId*/)
@@ -38,6 +38,7 @@ void DepthPrepassMeshProcessor::processMeshBatch(
Gfx::PRenderCommand renderCommand = graphics->createRenderCommand();
renderCommand->setViewport(target);
Gfx::PPipelineLayout pipelineLayout = graphics->createPipelineLayout(baseLayout);
pipelineLayout->addDescriptorLayout(DepthPrepass::INDEX_MATERIAL, material->getDescriptorLayout());
pipelineLayout->create();
Gfx::PDescriptorSet materialSet = material->createDescriptorSet();
@@ -61,10 +62,10 @@ void DepthPrepassMeshProcessor::processMeshBatch(
collection->fragmentShader,
true);
}
std::unique_lock lock(commandLock);
std::scoped_lock lock(commandLock);
renderCommands.add(renderCommand);
//std::cout << "Finished depth job" << std::endl;
//co_return;
co_return;
}
DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source)
@@ -128,10 +129,9 @@ MainJob DepthPrepass::render()
for (auto &&meshBatch : passData.staticDrawList)
{
//jobs.add(
processor->processMeshBatch(meshBatch, renderPass, depthPrepassLayout, primitiveLayout, descriptorSets);
co_await processor->processMeshBatch(meshBatch, renderPass, depthPrepassLayout, primitiveLayout, descriptorSets);
}
//co_await Job::all(jobs);
//std::cout << "Finished waiting depth jobs " << std::endl;
graphics->executeCommands(processor->getRenderCommands());
graphics->endRenderPass();
co_return;
@@ -11,7 +11,7 @@ public:
DepthPrepassMeshProcessor(Gfx::PViewport viewport, Gfx::PGraphics graphics);
virtual ~DepthPrepassMeshProcessor();
virtual void processMeshBatch(
virtual Job processMeshBatch(
const MeshBatch& batch,
const Gfx::PRenderPass& renderPass,
Gfx::PPipelineLayout pipelineLayout,
@@ -27,7 +27,7 @@ DECLARE_REF(CameraActor)
DECLARE_REF(CameraComponent)
struct DepthPrepassData
{
Array<StaticMeshBatch> staticDrawList;
std::vector<StaticMeshBatch> staticDrawList;
};
class DepthPrepass : public RenderPass<DepthPrepassData>
{
@@ -1,6 +1,7 @@
#include "MeshProcessor.h"
#include "Graphics/Graphics.h"
#include "Graphics/VertexShaderInput.h"
#include "Graphics/Vulkan/VulkanGraphicsResources.h"
using namespace Seele;
@@ -32,8 +33,6 @@ void MeshProcessor::buildMeshDrawCommand(
GraphicsPipelineCreateInfo pipelineInitializer;
pipelineInitializer.topology = meshBatch.topology;
Gfx::PVertexDeclaration vertexDecl = positionOnly ? vertexInput->getPositionDeclaration() : vertexInput->getDeclaration();
pipelineInitializer.vertexDeclaration = vertexDecl;
pipelineInitializer.vertexShader = vertexShader;
pipelineInitializer.controlShader = controlShader;
pipelineInitializer.evalShader = evaluationShader;
@@ -46,10 +45,12 @@ void MeshProcessor::buildMeshDrawCommand(
if(positionOnly)
{
vertexInput->getPositionOnlyStream(vertexStreams);
pipelineInitializer.vertexDeclaration = vertexInput->getPositionDeclaration();
}
else
{
vertexInput->getStreams(vertexStreams);
pipelineInitializer.vertexDeclaration = vertexInput->getDeclaration();
}
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInitializer);
drawCommand->bindPipeline(pipeline);
@@ -17,7 +17,7 @@ public:
protected:
PScene scene;
Gfx::PGraphics graphics;
virtual void processMeshBatch(
virtual Job processMeshBatch(
const MeshBatch& batch,
// const PPrimitiveComponent primitiveComponent,
const Gfx::PRenderPass& renderPass,
@@ -77,7 +77,7 @@ void GpuCrashTracker::Initialize()
void GpuCrashTracker::OnCrashDump(const void* pGpuCrashDump, const uint32_t gpuCrashDumpSize)
{
// Make sure only one thread at a time...
std::unique_lock<std::mutex> lock(m_mutex);
std::scoped_lock<std::mutex> lock(m_mutex);
// Write to file for later in-depth analysis with Nsight Graphics.
WriteGpuCrashDumpToFile(pGpuCrashDump, gpuCrashDumpSize);
@@ -87,7 +87,7 @@ void GpuCrashTracker::OnCrashDump(const void* pGpuCrashDump, const uint32_t gpuC
void GpuCrashTracker::OnShaderDebugInfo(const void* pShaderDebugInfo, const uint32_t shaderDebugInfoSize)
{
// Make sure only one thread at a time...
std::unique_lock<std::mutex> lock(m_mutex);
std::scoped_lock<std::mutex> lock(m_mutex);
// Get shader debug information identifier
GFSDK_Aftermath_ShaderDebugInfoIdentifier identifier = {};
+10 -7
View File
@@ -74,7 +74,7 @@ Allocation::~Allocation()
PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDeviceSize alignment)
{
std::unique_lock lck(lock);
std::scoped_lock lck(lock);
if (isDedicated)
{
if (activeAllocations.empty() && requestedSize == bytesAllocated)
@@ -134,7 +134,7 @@ void Allocation::markFree(SubAllocation *allocation)
PSubAllocation freeRangeToDelete;
{
std::unique_lock lck(lock);
std::scoped_lock lck(lock);
//Join lower bound
for (auto freeRange : freeRanges)
{
@@ -204,7 +204,7 @@ Allocator::Allocator(PGraphics graphics)
Allocator::~Allocator()
{
std::unique_lock lck(lock);
std::scoped_lock lck(lock);
for (auto heap : heaps)
{
for (auto alloc : heap.allocations)
@@ -219,7 +219,7 @@ Allocator::~Allocator()
PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo)
{
std::unique_lock lck(lock);
std::scoped_lock lck(lock);
const VkMemoryRequirements &requirements = memRequirements2.memoryRequirements;
uint8 memoryTypeIndex;
VK_CHECK(findMemoryType(requirements.memoryTypeBits, properties, &memoryTypeIndex));
@@ -252,7 +252,7 @@ PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2
void Allocator::free(Allocation *allocation)
{
std::unique_lock lck(lock);
std::scoped_lock lck(lock);
for (auto heap : heaps)
{
for (uint32 i = 0; i < heap.allocations.size(); ++i)
@@ -307,7 +307,7 @@ void StagingManager::clearPending()
PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageFlags usage, bool bCPURead)
{
std::unique_lock l(lock);
std::scoped_lock l(lock);
for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it)
{
auto freeBuffer = *it;
@@ -323,6 +323,9 @@ PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageF
PStagingBuffer stagingBuffer = new StagingBuffer();
VkBufferCreateInfo stagingBufferCreateInfo = init::BufferCreateInfo(usage, size);
stagingBufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
uint32 queueIndex = graphics->getFamilyMapping().getQueueTypeFamilyIndex(Gfx::QueueType::DEDICATED_TRANSFER);
stagingBufferCreateInfo.queueFamilyIndexCount = 1;
stagingBufferCreateInfo.pQueueFamilyIndices = &queueIndex;
VkDevice vulkanDevice = graphics->getDevice();
VK_CHECK(vkCreateBuffer(vulkanDevice, &stagingBufferCreateInfo, nullptr, &stagingBuffer->buffer));
@@ -355,7 +358,7 @@ PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageF
void StagingManager::releaseStagingBuffer(PStagingBuffer buffer)
{
std::unique_lock l(lock);
std::scoped_lock l(lock);
freeBuffers.add(buffer);
activeBuffers.remove(activeBuffers.find(buffer.getHandle()));
}
+309 -309
View File
@@ -10,277 +10,277 @@ using namespace Seele::Vulkan;
struct PendingBuffer
{
PStagingBuffer stagingBuffer;
Gfx::QueueType prevQueue;
bool bWriteOnly;
PStagingBuffer stagingBuffer;
Gfx::QueueType prevQueue;
bool bWriteOnly;
};
static Map<ShaderBuffer *, PendingBuffer> pendingBuffers;
ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic)
: graphics(graphics)
, currentBuffer(0)
, size(size)
, owner(queueType)
: graphics(graphics)
, currentBuffer(0)
, size(size)
, owner(queueType)
{
if(bDynamic)
{
numBuffers = Gfx::numFramesBuffered;
}
else
{
numBuffers = 1;
}
usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
VkBufferCreateInfo info =
init::BufferCreateInfo(
usage,
size);
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
uint32 queueFamilyIndex = graphics->getFamilyMapping().getQueueTypeFamilyIndex(queueType);
info.pQueueFamilyIndices = &queueFamilyIndex;
info.queueFamilyIndexCount = 0;
VkBufferMemoryRequirementsInfo2 bufferReqInfo;
bufferReqInfo.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2;
bufferReqInfo.pNext = nullptr;
VkMemoryDedicatedRequirements dedicatedRequirements;
dedicatedRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
dedicatedRequirements.pNext = nullptr;
VkMemoryRequirements2 memRequirements;
memRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
memRequirements.pNext = &dedicatedRequirements;
for (uint32 i = 0; i < numBuffers; ++i)
{
VK_CHECK(vkCreateBuffer(graphics->getDevice(), &info, nullptr, &buffers[i].buffer));
bufferReqInfo.buffer = buffers[i].buffer;
vkGetBufferMemoryRequirements2(graphics->getDevice(), &bufferReqInfo, &memRequirements);
auto temp = graphics->getAllocator()->allocate(memRequirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, buffers[i].buffer);
buffers[i].allocation = temp;
vkBindBufferMemory(graphics->getDevice(), buffers[i].buffer, buffers[i].allocation->getHandle(), buffers[i].allocation->getOffset());
}
if(bDynamic)
{
numBuffers = Gfx::numFramesBuffered;
}
else
{
numBuffers = 1;
}
usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
VkBufferCreateInfo info =
init::BufferCreateInfo(
usage,
size);
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
uint32 queueFamilyIndex = graphics->getFamilyMapping().getQueueTypeFamilyIndex(queueType);
info.pQueueFamilyIndices = &queueFamilyIndex;
info.queueFamilyIndexCount = 1;
VkBufferMemoryRequirementsInfo2 bufferReqInfo;
bufferReqInfo.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2;
bufferReqInfo.pNext = nullptr;
VkMemoryDedicatedRequirements dedicatedRequirements;
dedicatedRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
dedicatedRequirements.pNext = nullptr;
VkMemoryRequirements2 memRequirements;
memRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
memRequirements.pNext = &dedicatedRequirements;
for (uint32 i = 0; i < numBuffers; ++i)
{
VK_CHECK(vkCreateBuffer(graphics->getDevice(), &info, nullptr, &buffers[i].buffer));
bufferReqInfo.buffer = buffers[i].buffer;
vkGetBufferMemoryRequirements2(graphics->getDevice(), &bufferReqInfo, &memRequirements);
auto temp = graphics->getAllocator()->allocate(memRequirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, buffers[i].buffer);
buffers[i].allocation = temp;
vkBindBufferMemory(graphics->getDevice(), buffers[i].buffer, buffers[i].allocation->getHandle(), buffers[i].allocation->getOffset());
}
}
ShaderBuffer::~ShaderBuffer()
{
PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
VkDevice device = graphics->getDevice();
auto deletionLambda = [cmdBuffer, device](VkBuffer buffer) -> Job
{
//co_await cmdBuffer->asyncWait();
//vkDestroyBuffer(device, buffer, nullptr);
PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
VkDevice device = graphics->getDevice();
auto deletionLambda = [cmdBuffer, device](VkBuffer buffer) -> Job
{
//co_await cmdBuffer->asyncWait();
//vkDestroyBuffer(device, buffer, nullptr);
co_return;
};
for (uint32 i = 0; i < numBuffers; ++i)
{
deletionLambda(buffers[i].buffer);
buffers[i].allocation = nullptr;
}
graphics = nullptr;
for (uint32 i = 0; i < numBuffers; ++i)
{
deletionLambda(buffers[i].buffer);
buffers[i].allocation = nullptr;
}
graphics = nullptr;
}
VkDeviceSize ShaderBuffer::getOffset() const
{
return buffers[currentBuffer].allocation->getOffset();
return buffers[currentBuffer].allocation->getOffset();
}
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
VkBufferMemoryBarrier barrier =
init::BufferMemoryBarrier();
PCommandBufferManager sourceManager = graphics->getQueueCommands(owner);
PCommandBufferManager dstManager = nullptr;
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
barrier.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner);
barrier.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner);
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
if (owner == Gfx::QueueType::TRANSFER || owner == Gfx::QueueType::DEDICATED_TRANSFER)
{
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
}
else if (owner == Gfx::QueueType::COMPUTE)
{
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
}
else if (owner == Gfx::QueueType::GRAPHICS)
{
barrier.srcAccessMask = getSourceAccessMask();
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
}
if (newOwner == Gfx::QueueType::TRANSFER)
{
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstManager = graphics->getTransferCommands();
}
else if (newOwner == Gfx::QueueType::DEDICATED_TRANSFER)
{
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstManager = graphics->getDedicatedTransferCommands();
}
else if (newOwner == Gfx::QueueType::COMPUTE)
{
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
dstManager = graphics->getComputeCommands();
}
else if (newOwner == Gfx::QueueType::GRAPHICS)
{
barrier.dstAccessMask = getDestAccessMask();
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
dstManager = graphics->getGraphicsCommands();
}
VkCommandBuffer srcCommand = sourceManager->getCommands()->getHandle();
VkCommandBuffer dstCommand = dstManager->getCommands()->getHandle();
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
barrier.offset = 0;
barrier.size = size;
for (uint32 i = 0; i < numBuffers; ++i)
{
dynamicBarriers[i] = barrier;
dynamicBarriers[i].buffer = buffers[i].buffer;
}
vkCmdPipelineBarrier(srcCommand, srcStage, srcStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
vkCmdPipelineBarrier(dstCommand, dstStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
sourceManager->submitCommands();
VkBufferMemoryBarrier barrier =
init::BufferMemoryBarrier();
PCommandBufferManager sourceManager = graphics->getQueueCommands(owner);
PCommandBufferManager dstManager = nullptr;
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
barrier.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner);
barrier.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner);
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
if (owner == Gfx::QueueType::TRANSFER || owner == Gfx::QueueType::DEDICATED_TRANSFER)
{
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
}
else if (owner == Gfx::QueueType::COMPUTE)
{
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
}
else if (owner == Gfx::QueueType::GRAPHICS)
{
barrier.srcAccessMask = getSourceAccessMask();
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
}
if (newOwner == Gfx::QueueType::TRANSFER)
{
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstManager = graphics->getTransferCommands();
}
else if (newOwner == Gfx::QueueType::DEDICATED_TRANSFER)
{
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstManager = graphics->getDedicatedTransferCommands();
}
else if (newOwner == Gfx::QueueType::COMPUTE)
{
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
dstManager = graphics->getComputeCommands();
}
else if (newOwner == Gfx::QueueType::GRAPHICS)
{
barrier.dstAccessMask = getDestAccessMask();
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
dstManager = graphics->getGraphicsCommands();
}
VkCommandBuffer srcCommand = sourceManager->getCommands()->getHandle();
VkCommandBuffer dstCommand = dstManager->getCommands()->getHandle();
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
barrier.offset = 0;
barrier.size = size;
for (uint32 i = 0; i < numBuffers; ++i)
{
dynamicBarriers[i] = barrier;
dynamicBarriers[i].buffer = buffers[i].buffer;
}
vkCmdPipelineBarrier(srcCommand, srcStage, srcStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
vkCmdPipelineBarrier(dstCommand, dstStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
sourceManager->submitCommands();
}
void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
PCmdBuffer commandBuffer = graphics->getQueueCommands(owner)->getCommands();
VkBufferMemoryBarrier barrier = init::BufferMemoryBarrier();
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstAccessMask = dstAccess;
barrier.srcAccessMask = srcAccess;
barrier.offset = 0;
barrier.size = size;
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
for(uint32 i = 0; i < numBuffers; ++i)
{
dynamicBarriers[i] = barrier;
dynamicBarriers[i].buffer = buffers[i].buffer;
}
vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
PCmdBuffer commandBuffer = graphics->getQueueCommands(owner)->getCommands();
VkBufferMemoryBarrier barrier = init::BufferMemoryBarrier();
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstAccessMask = dstAccess;
barrier.srcAccessMask = srcAccess;
barrier.offset = 0;
barrier.size = size;
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
for(uint32 i = 0; i < numBuffers; ++i)
{
dynamicBarriers[i] = barrier;
dynamicBarriers[i].buffer = buffers[i].buffer;
}
vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
}
void *ShaderBuffer::lock(bool bWriteOnly)
{
void *data = nullptr;
void *data = nullptr;
/*if (bVolatile)
{
if (lockMode == RLM_ReadOnly)
{
assert(0);
}
else
{
throw new std::logic_error("TODO implement volatile buffers");
//device->getRHIDevice()->getTemp
}
}*/
//assert(bStatic || bDynamic || bUAV);
/*if (bVolatile)
{
if (lockMode == RLM_ReadOnly)
{
assert(0);
}
else
{
throw new std::logic_error("TODO implement volatile buffers");
//device->getRHIDevice()->getTemp
}
}*/
//assert(bStatic || bDynamic || bUAV);
PendingBuffer pending;
pending.bWriteOnly = bWriteOnly;
pending.prevQueue = owner;
if (bWriteOnly)
{
//requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
data = stagingBuffer->getMappedPointer();
pending.stagingBuffer = stagingBuffer;
}
else
{
PCmdBuffer current = graphics->getQueueCommands(owner)->getCommands();
graphics->getQueueCommands(owner)->submitCommands();
current->waitForCommand();
PendingBuffer pending;
pending.bWriteOnly = bWriteOnly;
pending.prevQueue = owner;
if (bWriteOnly)
{
//requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
data = stagingBuffer->getMappedPointer();
pending.stagingBuffer = stagingBuffer;
}
else
{
PCmdBuffer current = graphics->getQueueCommands(owner)->getCommands();
graphics->getQueueCommands(owner)->submitCommands();
current->waitForCommand();
requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
VkCommandBuffer handle = graphics->getQueueCommands(owner)->getCommands()->getHandle();
requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
VkCommandBuffer handle = graphics->getQueueCommands(owner)->getCommands()->getHandle();
VkBufferMemoryBarrier barrier =
init::BufferMemoryBarrier();
barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
barrier.buffer = buffers[currentBuffer].buffer;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.offset = 0;
barrier.size = size;
vkCmdPipelineBarrier(handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr);
VkBufferMemoryBarrier barrier =
init::BufferMemoryBarrier();
barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
barrier.buffer = buffers[currentBuffer].buffer;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.offset = 0;
barrier.size = size;
vkCmdPipelineBarrier(handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr);
PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true);
PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true);
VkBufferCopy regions;
regions.size = size;
regions.srcOffset = 0;
regions.dstOffset = 0;
VkBufferCopy regions;
regions.size = size;
regions.srcOffset = 0;
regions.dstOffset = 0;
vkCmdCopyBuffer(handle, buffers[currentBuffer].buffer, stagingBuffer->getHandle(), 1, &regions);
vkCmdCopyBuffer(handle, buffers[currentBuffer].buffer, stagingBuffer->getHandle(), 1, &regions);
graphics->getQueueCommands(owner)->submitCommands();
vkQueueWaitIdle(graphics->getQueueCommands(owner)->getQueue()->getHandle());
graphics->getQueueCommands(owner)->submitCommands();
vkQueueWaitIdle(graphics->getQueueCommands(owner)->getQueue()->getHandle());
stagingBuffer->flushMappedMemory();
pending.stagingBuffer = stagingBuffer;
stagingBuffer->flushMappedMemory();
pending.stagingBuffer = stagingBuffer;
data = stagingBuffer->getMappedPointer();
}
pendingBuffers[this] = pending;
data = stagingBuffer->getMappedPointer();
}
pendingBuffers[this] = pending;
assert(data);
return data;
assert(data);
return data;
}
void ShaderBuffer::unlock()
{
auto found = pendingBuffers.find(this);
if (found != pendingBuffers.end())
{
PendingBuffer pending = found->value;
pending.stagingBuffer->flushMappedMemory();
pendingBuffers.erase(this);
if (pending.bWriteOnly)
{
PStagingBuffer stagingBuffer = pending.stagingBuffer;
PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
auto found = pendingBuffers.find(this);
if (found != pendingBuffers.end())
{
PendingBuffer pending = found->value;
pending.stagingBuffer->flushMappedMemory();
pendingBuffers.erase(this);
if (pending.bWriteOnly)
{
PStagingBuffer stagingBuffer = pending.stagingBuffer;
PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
VkBufferCopy region;
std::memset(&region, 0, sizeof(VkBufferCopy));
region.size = size;
vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, &region);
graphics->getQueueCommands(owner)->submitCommands();
}
//requestOwnershipTransfer(pending.prevQueue);
graphics->getStagingManager()->releaseStagingBuffer(pending.stagingBuffer);
}
VkBufferCopy region;
std::memset(&region, 0, sizeof(VkBufferCopy));
region.size = size;
vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, &region);
graphics->getQueueCommands(owner)->submitCommands();
}
//requestOwnershipTransfer(pending.prevQueue);
graphics->getStagingManager()->releaseStagingBuffer(pending.stagingBuffer);
}
}
UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &createInfo)
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.resourceData)
, Vulkan::ShaderBuffer(graphics, createInfo.resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, createInfo.bDynamic)
, dedicatedStagingBuffer(nullptr)
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.resourceData)
, Vulkan::ShaderBuffer(graphics, createInfo.resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, createInfo.bDynamic)
, dedicatedStagingBuffer(nullptr)
{
if(createInfo.bDynamic)
{
dedicatedStagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(createInfo.resourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
}
if (createInfo.resourceData.data != nullptr)
{
void *data = lock();
std::memcpy(data, createInfo.resourceData.data, createInfo.resourceData.size);
unlock();
}
if(createInfo.bDynamic)
{
dedicatedStagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(createInfo.resourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
}
if (createInfo.resourceData.data != nullptr)
{
void *data = lock();
std::memcpy(data, createInfo.resourceData.data, createInfo.resourceData.size);
unlock();
}
}
UniformBuffer::~UniformBuffer()
@@ -290,52 +290,52 @@ UniformBuffer::~UniformBuffer()
bool UniformBuffer::updateContents(const BulkResourceData &resourceData)
{
if(!Gfx::UniformBuffer::updateContents(resourceData))
{
// no update was performed, skip
return false;
}
{
// no update was performed, skip
return false;
}
void* data = lock();
std::memcpy(data, resourceData.data, resourceData.size);
unlock();
return true;
return true;
}
void* UniformBuffer::lock(bool bWriteOnly)
{
if(dedicatedStagingBuffer != nullptr)
{
return dedicatedStagingBuffer->getMappedPointer();
}
return ShaderBuffer::lock(bWriteOnly);
if(dedicatedStagingBuffer != nullptr)
{
return dedicatedStagingBuffer->getMappedPointer();
}
return ShaderBuffer::lock(bWriteOnly);
}
void UniformBuffer::unlock()
{
if(dedicatedStagingBuffer != nullptr)
{
dedicatedStagingBuffer->flushMappedMemory();
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
if(dedicatedStagingBuffer != nullptr)
{
dedicatedStagingBuffer->flushMappedMemory();
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
VkBufferCopy region;
std::memset(&region, 0, sizeof(VkBufferCopy));
region.size = ShaderBuffer::size;
vkCmdCopyBuffer(cmdHandle, dedicatedStagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, &region);
graphics->getQueueCommands(currentOwner)->submitCommands();
}
else
{
ShaderBuffer::unlock();
}
VkBufferCopy region;
std::memset(&region, 0, sizeof(VkBufferCopy));
region.size = ShaderBuffer::size;
vkCmdCopyBuffer(cmdHandle, dedicatedStagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, &region);
graphics->getQueueCommands(currentOwner)->submitCommands();
}
else
{
ShaderBuffer::unlock();
}
}
void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
{
Gfx::QueueOwnedResource::transferOwnership(newOwner);
Gfx::QueueOwnedResource::transferOwnership(newOwner);
}
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
}
void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
@@ -346,24 +346,24 @@ void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineSt
VkAccessFlags UniformBuffer::getSourceAccessMask()
{
return VK_ACCESS_MEMORY_WRITE_BIT;
return VK_ACCESS_MEMORY_WRITE_BIT;
}
VkAccessFlags UniformBuffer::getDestAccessMask()
{
return VK_ACCESS_UNIFORM_READ_BIT;
return VK_ACCESS_UNIFORM_READ_BIT;
}
StructuredBuffer::StructuredBuffer(PGraphics graphics, const StructuredBufferCreateInfo &resourceData)
: Gfx::StructuredBuffer(graphics->getFamilyMapping(), resourceData.resourceData)
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, resourceData.bDynamic)
: Gfx::StructuredBuffer(graphics->getFamilyMapping(), resourceData.resourceData)
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, resourceData.bDynamic)
{
if (resourceData.resourceData.data != nullptr)
{
void *data = lock();
std::memcpy(data, resourceData.resourceData.data, resourceData.resourceData.size);
unlock();
}
if (resourceData.resourceData.data != nullptr)
{
void *data = lock();
std::memcpy(data, resourceData.resourceData.data, resourceData.resourceData.size);
unlock();
}
}
StructuredBuffer::~StructuredBuffer()
@@ -373,49 +373,49 @@ StructuredBuffer::~StructuredBuffer()
bool StructuredBuffer::updateContents(const BulkResourceData &resourceData)
{
Gfx::StructuredBuffer::updateContents(resourceData);
//We always want to update, as the contents could be different on the GPU
//We always want to update, as the contents could be different on the GPU
void* data = lock();
std::memcpy(data, resourceData.data, resourceData.size);
unlock();
return true;
return true;
}
void* StructuredBuffer::lock(bool bWriteOnly)
{
if(dedicatedStagingBuffer != nullptr)
{
return dedicatedStagingBuffer->getMappedPointer();
}
return ShaderBuffer::lock(bWriteOnly);
if(dedicatedStagingBuffer != nullptr)
{
return dedicatedStagingBuffer->getMappedPointer();
}
return ShaderBuffer::lock(bWriteOnly);
}
void StructuredBuffer::unlock()
{
if(dedicatedStagingBuffer != nullptr)
{
dedicatedStagingBuffer->flushMappedMemory();
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
if(dedicatedStagingBuffer != nullptr)
{
dedicatedStagingBuffer->flushMappedMemory();
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
VkBufferCopy region;
std::memset(&region, 0, sizeof(VkBufferCopy));
region.size = ShaderBuffer::size;
vkCmdCopyBuffer(cmdHandle, dedicatedStagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, &region);
graphics->getQueueCommands(currentOwner)->submitCommands();
}
else
{
ShaderBuffer::unlock();
}
VkBufferCopy region;
std::memset(&region, 0, sizeof(VkBufferCopy));
region.size = ShaderBuffer::size;
vkCmdCopyBuffer(cmdHandle, dedicatedStagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, &region);
graphics->getQueueCommands(currentOwner)->submitCommands();
}
else
{
ShaderBuffer::unlock();
}
}
void StructuredBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
{
Gfx::QueueOwnedResource::transferOwnership(newOwner);
Gfx::QueueOwnedResource::transferOwnership(newOwner);
}
void StructuredBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
}
void StructuredBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
@@ -426,24 +426,24 @@ void StructuredBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelin
VkAccessFlags StructuredBuffer::getSourceAccessMask()
{
return VK_ACCESS_MEMORY_WRITE_BIT;
return VK_ACCESS_MEMORY_WRITE_BIT;
}
VkAccessFlags StructuredBuffer::getDestAccessMask()
{
return VK_ACCESS_MEMORY_READ_BIT;
return VK_ACCESS_MEMORY_READ_BIT;
}
VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData)
: Gfx::VertexBuffer(graphics->getFamilyMapping(), resourceData.numVertices, resourceData.vertexSize, resourceData.resourceData.owner)
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner)
: Gfx::VertexBuffer(graphics->getFamilyMapping(), resourceData.numVertices, resourceData.vertexSize, resourceData.resourceData.owner)
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner)
{
if (resourceData.resourceData.data != nullptr)
{
void *data = lock();
std::memcpy(data, resourceData.resourceData.data, resourceData.resourceData.size);
unlock();
}
if (resourceData.resourceData.data != nullptr)
{
void *data = lock();
std::memcpy(data, resourceData.resourceData.data, resourceData.resourceData.size);
unlock();
}
}
VertexBuffer::~VertexBuffer()
@@ -452,12 +452,12 @@ VertexBuffer::~VertexBuffer()
void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
{
Gfx::QueueOwnedResource::transferOwnership(newOwner);
Gfx::QueueOwnedResource::transferOwnership(newOwner);
}
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
}
void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
@@ -468,24 +468,24 @@ void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineSta
VkAccessFlags VertexBuffer::getSourceAccessMask()
{
return VK_ACCESS_MEMORY_WRITE_BIT;
return VK_ACCESS_MEMORY_WRITE_BIT;
}
VkAccessFlags VertexBuffer::getDestAccessMask()
{
return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
}
IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData)
: Gfx::IndexBuffer(graphics->getFamilyMapping(), resourceData.resourceData.size, resourceData.indexType, resourceData.resourceData.owner)
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, currentOwner)
: Gfx::IndexBuffer(graphics->getFamilyMapping(), resourceData.resourceData.size, resourceData.indexType, resourceData.resourceData.owner)
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, currentOwner)
{
if (resourceData.resourceData.data != nullptr)
{
void *data = lock();
std::memcpy(data, resourceData.resourceData.data, resourceData.resourceData.size);
unlock();
}
if (resourceData.resourceData.data != nullptr)
{
void *data = lock();
std::memcpy(data, resourceData.resourceData.data, resourceData.resourceData.size);
unlock();
}
}
IndexBuffer::~IndexBuffer()
@@ -494,12 +494,12 @@ IndexBuffer::~IndexBuffer()
void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
{
Gfx::QueueOwnedResource::transferOwnership(newOwner);
Gfx::QueueOwnedResource::transferOwnership(newOwner);
}
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
}
void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
@@ -510,10 +510,10 @@ void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStag
VkAccessFlags IndexBuffer::getSourceAccessMask()
{
return VK_ACCESS_MEMORY_WRITE_BIT;
return VK_ACCESS_MEMORY_WRITE_BIT;
}
VkAccessFlags IndexBuffer::getDestAccessMask()
{
return VK_ACCESS_INDEX_READ_BIT;
return VK_ACCESS_INDEX_READ_BIT;
}
@@ -16,16 +16,13 @@ using namespace Seele::Vulkan;
CmdBuffer::CmdBuffer(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferManager manager)
: graphics(graphics)
, manager(manager)
, renderPass(nullptr)
, framebuffer(nullptr)
, subpassIndex(0)
, owner(cmdPool)
{
VkCommandBufferAllocateInfo allocInfo =
init::CommandBufferAllocateInfo(cmdPool,
VK_COMMAND_BUFFER_LEVEL_PRIMARY,
1);
std::unique_lock lock(handleLock);
std::scoped_lock lock(handleLock);
VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle))
fence = new Fence(graphics);
@@ -34,10 +31,8 @@ CmdBuffer::CmdBuffer(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferMa
CmdBuffer::~CmdBuffer()
{
std::unique_lock lock(handleLock);
std::scoped_lock lock(handleLock);
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
renderPass = nullptr;
framebuffer = nullptr;
waitSemaphores.clear();
}
@@ -46,24 +41,22 @@ void CmdBuffer::begin()
VkCommandBufferBeginInfo beginInfo =
init::CommandBufferBeginInfo();
beginInfo.pInheritanceInfo = nullptr;
std::unique_lock lock(handleLock);
std::scoped_lock lock(handleLock);
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
state = State::InsideBegin;
}
void CmdBuffer::end()
{
std::unique_lock lock(handleLock);
std::scoped_lock lock(handleLock);
VK_CHECK(vkEndCommandBuffer(handle));
state = State::Ended;
}
void CmdBuffer::beginRenderPass(PRenderPass newRenderPass, PFramebuffer newFramebuffer)
void CmdBuffer::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer)
{
assert(state == State::InsideBegin);
std::unique_lock lock(handleLock);
renderPass = newRenderPass;
framebuffer = newFramebuffer;
std::scoped_lock lock(handleLock);
VkRenderPassBeginInfo beginInfo =
init::RenderPassBeginInfo();
@@ -74,15 +67,13 @@ void CmdBuffer::beginRenderPass(PRenderPass newRenderPass, PFramebuffer newFrame
beginInfo.framebuffer = framebuffer->getHandle();
vkCmdBeginRenderPass(handle, &beginInfo, renderPass->getSubpassContents());
state = State::RenderPassActive;
//std::cout << "Beginning renderPass" << std::endl;
}
void CmdBuffer::endRenderPass()
{
std::unique_lock lock(handleLock);
std::scoped_lock lock(handleLock);
vkCmdEndRenderPass(handle);
state = State::InsideBegin;
//std::cout << "Ending renderPass" << std::endl;
}
void CmdBuffer::executeCommands(const Array<Gfx::PRenderCommand>& commands)
@@ -90,9 +81,10 @@ void CmdBuffer::executeCommands(const Array<Gfx::PRenderCommand>& commands)
assert(state == State::RenderPassActive);
if(commands.size() == 0)
{
std::cout << "No commands provided" << std::endl;
return;
}
std::unique_lock lock(handleLock);
std::scoped_lock lock(handleLock);
Array<VkCommandBuffer> cmdBuffers(commands.size());
for (uint32 i = 0; i < commands.size(); ++i)
{
@@ -111,7 +103,7 @@ void CmdBuffer::executeCommands(const Array<Gfx::PRenderCommand>& commands)
void CmdBuffer::executeCommands(const Array<Gfx::PComputeCommand>& commands)
{
std::unique_lock lock(handleLock);
std::scoped_lock lock(handleLock);
if(commands.size() == 0)
{
return;
@@ -134,14 +126,14 @@ void CmdBuffer::executeCommands(const Array<Gfx::PComputeCommand>& commands)
void CmdBuffer::addWaitSemaphore(VkPipelineStageFlags flags, PSemaphore semaphore)
{
std::unique_lock lock(handleLock);
std::scoped_lock lock(handleLock);
waitSemaphores.add(semaphore);
waitFlags.add(flags);
}
void CmdBuffer::refreshFence()
{
std::unique_lock lock(handleLock);
std::scoped_lock lock(handleLock);
if (state == State::Submitted)
{
if (fence->isSignaled())
@@ -174,7 +166,7 @@ void CmdBuffer::refreshFence()
void CmdBuffer::waitForCommand(uint32 timeout)
{
std::unique_lock lock(handleLock);
std::scoped_lock lock(handleLock);
fence->wait(timeout);
refreshFence();
}
@@ -212,7 +204,7 @@ RenderCommand::~RenderCommand()
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
}
void RenderCommand::begin(PCmdBuffer parent)
void RenderCommand::begin(PRenderPass renderPass, PFramebuffer framebuffer)
{
threadId = std::this_thread::get_id();
ready = false;
@@ -220,9 +212,9 @@ void RenderCommand::begin(PCmdBuffer parent)
init::CommandBufferBeginInfo();
VkCommandBufferInheritanceInfo inheritanceInfo =
init::CommandBufferInheritanceInfo();
inheritanceInfo.framebuffer = parent->framebuffer->getHandle();
inheritanceInfo.renderPass = parent->renderPass->getHandle();
inheritanceInfo.subpass = parent->subpassIndex;
inheritanceInfo.framebuffer = framebuffer->getHandle();
inheritanceInfo.renderPass = renderPass->getHandle();
inheritanceInfo.subpass = 0;
beginInfo.pInheritanceInfo = &inheritanceInfo;
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
@@ -230,13 +222,11 @@ void RenderCommand::begin(PCmdBuffer parent)
void RenderCommand::end()
{
assert(threadId == std::this_thread::get_id());
VK_CHECK(vkEndCommandBuffer(handle));
}
void RenderCommand::reset()
{
assert(threadId == std::this_thread::get_id());
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
boundDescriptors.clear();
ready = true;
@@ -420,7 +410,7 @@ CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
activeCmdBuffer = new CmdBuffer(graphics, commandPool, this);
activeCmdBuffer->begin();
std::unique_lock lock(allocatedBufferLock);
std::scoped_lock lock(allocatedBufferLock);
allocatedBuffers.add(activeCmdBuffer);
}
@@ -436,29 +426,29 @@ PCmdBuffer CommandBufferManager::getCommands()
return activeCmdBuffer;
}
PRenderCommand CommandBufferManager::createRenderCommand(const std::string& name)
PRenderCommand CommandBufferManager::createRenderCommand(PRenderPass renderPass, PFramebuffer framebuffer, const std::string& name)
{
std::unique_lock lck(allocatedRenderLock);
std::scoped_lock lck(allocatedRenderLock);
for (uint32 i = 0; i < allocatedRenderCommands.size(); ++i)
{
PRenderCommand cmdBuffer = allocatedRenderCommands[i];
if (cmdBuffer->isReady())
{
cmdBuffer->name = name;
cmdBuffer->begin(activeCmdBuffer);
cmdBuffer->begin(renderPass, framebuffer);
return cmdBuffer;
}
}
PRenderCommand result = new RenderCommand(graphics, commandPool);
result->name = name;
result->begin(activeCmdBuffer);
result->begin(renderPass, framebuffer);
allocatedRenderCommands.add(result);
return result;
}
PComputeCommand CommandBufferManager::createComputeCommand(const std::string& name)
{
std::unique_lock lck(allocatedComputeLock);
std::scoped_lock lck(allocatedComputeLock);
for (uint32 i = 0; i < allocatedComputeCommands.size(); ++i)
{
PComputeCommand cmdBuffer = allocatedComputeCommands[i];
@@ -495,7 +485,7 @@ void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
queue->submitCommandBuffer(activeCmdBuffer);
}
}
std::unique_lock lock(allocatedBufferLock);
std::scoped_lock lock(allocatedBufferLock);
for (uint32 i = 0; i < allocatedBuffers.size(); ++i)
{
PCmdBuffer cmdBuffer = allocatedBuffers[i];
@@ -47,10 +47,7 @@ public:
private:
PGraphics graphics;
PCommandBufferManager manager;
PRenderPass renderPass;
PFramebuffer framebuffer;
PFence fence;
uint32 subpassIndex;
State state;
VkViewport currentViewport;
VkRect2D currentScissor;
@@ -79,7 +76,7 @@ public:
{
return handle;
}
void begin(PCmdBuffer parent);
void begin(PRenderPass renderPass, PFramebuffer framebuffer);
void end();
void reset();
virtual bool isReady() override;
@@ -145,7 +142,7 @@ public:
return queue;
}
PCmdBuffer getCommands();
PRenderCommand createRenderCommand(const std::string& name);
PRenderCommand createRenderCommand(PRenderPass renderPass, PFramebuffer framebuffer, const std::string& name);
PComputeCommand createComputeCommand(const std::string& name);
VkCommandPool getPoolHandle() const
{
@@ -54,7 +54,7 @@ PipelineLayout::~PipelineLayout()
{
if (layoutHandle != VK_NULL_HANDLE)
{
vkDestroyPipelineLayout(graphics->getDevice(), layoutHandle, nullptr);
//vkDestroyPipelineLayout(graphics->getDevice(), layoutHandle, nullptr);
}
}
@@ -29,12 +29,12 @@ DEFINE_REF(DescriptorLayout)
class PipelineLayout : public Gfx::PipelineLayout
{
public:
PipelineLayout(PGraphics graphics)
: graphics(graphics)
PipelineLayout(PGraphics graphics, Gfx::PPipelineLayout baseLayout)
: Gfx::PipelineLayout(baseLayout)
, graphics(graphics)
, layoutHash(0)
, layoutHandle(VK_NULL_HANDLE)
{
}
{}
virtual ~PipelineLayout();
virtual void create();
virtual void reset();
+28 -29
View File
@@ -14,6 +14,11 @@
using namespace Seele::Vulkan;
thread_local PCommandBufferManager Seele::Vulkan::Graphics::graphicsCommands = nullptr;
thread_local PCommandBufferManager Seele::Vulkan::Graphics::computeCommands = nullptr;
thread_local PCommandBufferManager Seele::Vulkan::Graphics::transferCommands = nullptr;
thread_local PCommandBufferManager Seele::Vulkan::Graphics::dedicatedTransferCommands = nullptr;
Graphics::Graphics()
: instance(VK_NULL_HANDLE)
, handle(VK_NULL_HANDLE)
@@ -52,7 +57,7 @@ Gfx::PWindow Graphics::createWindow(const WindowCreateInfo &createInfo)
Gfx::PViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreateInfo &viewportInfo)
{
PViewport result = new Viewport(this, owner, viewportInfo);
std::unique_lock lock(viewportLock);
std::scoped_lock lock(viewportLock);
viewports.add(result);
return result;
}
@@ -67,7 +72,7 @@ void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
uint32 framebufferHash = rp->getFramebufferHash();
PFramebuffer framebuffer;
{
std::unique_lock lock(allocatedFrameBufferLock);
std::scoped_lock lock(allocatedFrameBufferLock);
auto found = allocatedFramebuffers.find(framebufferHash);
if (found == allocatedFramebuffers.end())
{
@@ -80,12 +85,18 @@ void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
}
}
getGraphicsCommands()->getCommands()->beginRenderPass(rp, framebuffer);
std::scoped_lock lock(renderPassLock);
activeRenderPass = rp;
activeFramebuffer = framebuffer;
}
void Graphics::endRenderPass()
{
getGraphicsCommands()->getCommands()->endRenderPass();
getGraphicsCommands()->submitCommands();
std::scoped_lock lock(renderPassLock);
activeRenderPass = nullptr;
activeFramebuffer = nullptr;
}
void Graphics::executeCommands(const Array<Gfx::PRenderCommand>& commands)
@@ -128,7 +139,7 @@ Gfx::PIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkD
}
Gfx::PRenderCommand Graphics::createRenderCommand(const std::string& name)
{
PRenderCommand cmdBuffer = getGraphicsCommands()->createRenderCommand(name);
PRenderCommand cmdBuffer = getGraphicsCommands()->createRenderCommand(activeRenderPass, activeFramebuffer, name);
return cmdBuffer;
}
@@ -206,9 +217,9 @@ Gfx::PDescriptorLayout Graphics::createDescriptorLayout(const std::string& name)
PDescriptorLayout layout = new DescriptorLayout(this, name);
return layout;
}
Gfx::PPipelineLayout Graphics::createPipelineLayout()
Gfx::PPipelineLayout Graphics::createPipelineLayout(Gfx::PPipelineLayout baseLayout)
{
PPipelineLayout layout = new PipelineLayout(this);
PPipelineLayout layout = new PipelineLayout(this, baseLayout);
return layout;
}
@@ -295,49 +306,37 @@ PCommandBufferManager Graphics::getQueueCommands(Gfx::QueueType queueType)
throw new std::logic_error("invalid queue type");
}
}
std::mutex graphicsCommandLock;
PCommandBufferManager Graphics::getGraphicsCommands()
{
std::unique_lock lock(graphicsCommandLock);
auto id = std::this_thread::get_id();
if(graphicsCommands.find(id) == graphicsCommands.end())
if(graphicsCommands == nullptr)
{
graphicsCommands[id] = new CommandBufferManager(this, graphicsQueue);
graphicsCommands = new CommandBufferManager(this, graphicsQueue);
}
return graphicsCommands[id];
return graphicsCommands;
}
std::mutex computeCommandLock;
PCommandBufferManager Graphics::getComputeCommands()
{
std::unique_lock lock(computeCommandLock);
auto id = std::this_thread::get_id();
if(computeCommands.find(id) == computeCommands.end())
if(computeCommands == nullptr)
{
computeCommands[id] = new CommandBufferManager(this, computeQueue);
computeCommands = new CommandBufferManager(this, computeQueue);
}
return computeCommands[id];
return computeCommands;
}
std::mutex transferCommandLock;
PCommandBufferManager Graphics::getTransferCommands()
{
std::unique_lock lock(transferCommandLock);
auto id = std::this_thread::get_id();
if(transferCommands.find(id) == transferCommands.end())
if(transferCommands == nullptr)
{
transferCommands[id] = new CommandBufferManager(this, transferQueue);
transferCommands = new CommandBufferManager(this, transferQueue);
}
return transferCommands[id];
return transferCommands;
}
std::mutex dedicatedCommandLock;
PCommandBufferManager Graphics::getDedicatedTransferCommands()
{
std::unique_lock lock(dedicatedCommandLock);
auto id = std::this_thread::get_id();
if(dedicatedTransferCommands.find(id) == dedicatedTransferCommands.end())
if(dedicatedTransferCommands == dedicatedTransferCommands)
{
dedicatedTransferCommands[id] = new CommandBufferManager(this, dedicatedTransferQueue);
dedicatedTransferCommands = new CommandBufferManager(this, dedicatedTransferQueue);
}
return dedicatedTransferCommands[id];
return dedicatedTransferCommands;
}
PAllocator Graphics::getAllocator()
{
+9 -5
View File
@@ -11,6 +11,7 @@ DECLARE_REF(Allocator)
DECLARE_REF(StagingManager)
DECLARE_REF(CommandBufferManager)
DECLARE_REF(Queue)
DECLARE_REF(RenderPass)
DECLARE_REF(Framebuffer)
DECLARE_REF(RenderCommand)
DECLARE_REF(PipelineCache)
@@ -63,7 +64,7 @@ public:
virtual Gfx::PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) override;
virtual Gfx::PDescriptorLayout createDescriptorLayout(const std::string& name = "") override;
virtual Gfx::PPipelineLayout createPipelineLayout() override;
virtual Gfx::PPipelineLayout createPipelineLayout(Gfx::PPipelineLayout baseLayout = nullptr) override;
virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) override;
protected:
@@ -82,10 +83,13 @@ protected:
PQueue transferQueue;
PQueue dedicatedTransferQueue;
PPipelineCache pipelineCache;
Map<std::thread::id, PCommandBufferManager> graphicsCommands;
Map<std::thread::id, PCommandBufferManager> computeCommands;
Map<std::thread::id, PCommandBufferManager> transferCommands;
Map<std::thread::id, PCommandBufferManager> dedicatedTransferCommands;
std::mutex renderPassLock;
PRenderPass activeRenderPass;
PFramebuffer activeFramebuffer;
thread_local static PCommandBufferManager graphicsCommands;
thread_local static PCommandBufferManager computeCommands;
thread_local static PCommandBufferManager transferCommands;
thread_local static PCommandBufferManager dedicatedTransferCommands;
VkPhysicalDeviceProperties props;
VkPhysicalDeviceFeatures features;
VkDebugReportCallbackEXT callback;
@@ -296,6 +296,8 @@ VkBufferMemoryBarrier init::BufferMemoryBarrier()
VkBufferMemoryBarrier bufferMemoryBarrier = {};
bufferMemoryBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
bufferMemoryBarrier.pNext = NULL;
bufferMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufferMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
return bufferMemoryBarrier;
}
@@ -323,7 +323,7 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
uint32 hash = crc.checksum();
VkPipeline pipelineHandle;
std::unique_lock lock(createdPipelinesLock);
std::scoped_lock lock(createdPipelinesLock);
auto foundPipeline = createdPipelines.find(hash);
if (foundPipeline != createdPipelines.end())
{
+1 -1
View File
@@ -22,7 +22,7 @@ Queue::~Queue()
void Queue::submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores, VkSemaphore *signalSemaphores)
{
std::unique_lock lck(queueLock);
std::scoped_lock lck(queueLock);
assert(cmdBuffer->state == CmdBuffer::State::Ended);
PFence fence = cmdBuffer->fence;