From b2718dde70b71a3c7469ffeda5ed92defde4a843 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Mon, 27 Dec 2021 15:04:53 +0100 Subject: [PATCH] Rendering works now --- src/Engine/Containers/Array.h | 2 +- src/Engine/Graphics/RenderPass/BasePass.cpp | 9 +- src/Engine/Graphics/RenderPass/BasePass.h | 2 +- .../Graphics/RenderPass/DepthPrepass.cpp | 15 +- src/Engine/Graphics/RenderPass/DepthPrepass.h | 2 +- .../Graphics/RenderPass/LightCullingPass.cpp | 2 +- .../Graphics/RenderPass/MeshProcessor.h | 2 +- .../Graphics/Vulkan/VulkanCommandBuffer.cpp | 4 +- .../Graphics/Vulkan/VulkanDescriptorSets.cpp | 461 +++++++++--------- .../Graphics/Vulkan/VulkanDescriptorSets.h | 1 + src/Engine/ThreadPool.cpp | 8 +- src/Engine/ThreadPool.h | 46 +- src/Engine/Window/SceneView.cpp | 38 +- src/Engine/Window/View.cpp | 2 +- src/Engine/main.cpp | 8 +- 15 files changed, 324 insertions(+), 278 deletions(-) diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h index ef5bec5..c91c52d 100644 --- a/src/Engine/Containers/Array.h +++ b/src/Engine/Containers/Array.h @@ -504,7 +504,7 @@ namespace Seele // As well as default initialize the others for(size_type i = arraySize; i < newSize; ++i) { - std::allocator_traits::construct(allocator, &_data[i], std::move(value)); + std::allocator_traits::construct(allocator, &newData[i], std::move(value)); } deallocateArray(_data, allocated); arraySize = newSize; diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 0a7687a..3062b64 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -20,7 +20,7 @@ BasePassMeshProcessor::~BasePassMeshProcessor() { } -Job BasePassMeshProcessor::processMeshBatch( +void BasePassMeshProcessor::processMeshBatch( const MeshBatch& batch, // const PPrimitiveComponent primitiveComponent, const Gfx::PRenderPass& renderPass, @@ -65,7 +65,7 @@ Job BasePassMeshProcessor::processMeshBatch( } std::unique_lock lock(commandLock); renderCommands.add(renderCommand); - co_return; + //co_return; } BasePass::BasePass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source) @@ -156,9 +156,10 @@ MainJob BasePass::render() List jobs; for (auto &&meshBatch : passData.staticDrawList) { - jobs.add(processor->processMeshBatch(meshBatch, renderPass, basePassLayout, primitiveLayout, descriptorSets)); + //jobs.add( + processor->processMeshBatch(meshBatch, renderPass, basePassLayout, primitiveLayout, descriptorSets); } - co_await Job::all(jobs); + //co_await Job::all(jobs); graphics->executeCommands(processor->getRenderCommands()); graphics->endRenderPass(); co_return; diff --git a/src/Engine/Graphics/RenderPass/BasePass.h b/src/Engine/Graphics/RenderPass/BasePass.h index b1ac803..7822500 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.h +++ b/src/Engine/Graphics/RenderPass/BasePass.h @@ -11,7 +11,7 @@ public: BasePassMeshProcessor(Gfx::PViewport viewport, Gfx::PGraphics graphics, uint8 translucentBasePass); virtual ~BasePassMeshProcessor(); - virtual Job processMeshBatch( + virtual void processMeshBatch( const MeshBatch& batch, // const PPrimitiveComponent primitiveComponent, const Gfx::PRenderPass& renderPass, diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index 20888c6..e9fd5df 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp @@ -18,7 +18,7 @@ DepthPrepassMeshProcessor::~DepthPrepassMeshProcessor() { } -Job DepthPrepassMeshProcessor::processMeshBatch( +void DepthPrepassMeshProcessor::processMeshBatch( const MeshBatch& batch, // const PPrimitiveComponent primitiveComponent, const Gfx::PRenderPass& renderPass, @@ -27,7 +27,7 @@ Job DepthPrepassMeshProcessor::processMeshBatch( Array descriptorSets, int32 /*staticMeshId*/) { - std::cout << "Depth job started" << std::endl; + //std::cout << "Depth job started" << std::endl; PMaterialAsset material = batch.material; //const Gfx::MaterialShadingModel shadingModel = material->getShadingModel(); @@ -63,8 +63,8 @@ Job DepthPrepassMeshProcessor::processMeshBatch( } std::unique_lock lock(commandLock); renderCommands.add(renderCommand); - std::cout << "Finished depth job" << std::endl; - co_return; + //std::cout << "Finished depth job" << std::endl; + //co_return; } DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source) @@ -127,10 +127,11 @@ MainJob DepthPrepass::render() List jobs; for (auto &&meshBatch : passData.staticDrawList) { - jobs.add(processor->processMeshBatch(meshBatch, renderPass, depthPrepassLayout, primitiveLayout, descriptorSets)); + //jobs.add( + processor->processMeshBatch(meshBatch, renderPass, depthPrepassLayout, primitiveLayout, descriptorSets); } - co_await Job::all(jobs); - std::cout << "Finished waiting depth jobs " << std::endl; + //co_await Job::all(jobs); + //std::cout << "Finished waiting depth jobs " << std::endl; graphics->executeCommands(processor->getRenderCommands()); graphics->endRenderPass(); co_return; diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.h b/src/Engine/Graphics/RenderPass/DepthPrepass.h index 6be5163..55d91e4 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.h +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.h @@ -11,7 +11,7 @@ public: DepthPrepassMeshProcessor(Gfx::PViewport viewport, Gfx::PGraphics graphics); virtual ~DepthPrepassMeshProcessor(); - virtual Job processMeshBatch( + virtual void processMeshBatch( const MeshBatch& batch, const Gfx::PRenderPass& renderPass, Gfx::PPipelineLayout pipelineLayout, diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index fdd0a48..b05764d 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -75,7 +75,7 @@ MainJob LightCullingPass::beginFrame() lightEnvDescriptorSet->updateBuffer(2, pointLightBuffer); lightEnvDescriptorSet->updateBuffer(3, numPointLightBuffer); lightEnvDescriptorSet->writeChanges(); - std::cout << "Finished light culling beginFrame()" << std::endl; + //std::cout << "Finished light culling beginFrame()" << std::endl; co_return; } diff --git a/src/Engine/Graphics/RenderPass/MeshProcessor.h b/src/Engine/Graphics/RenderPass/MeshProcessor.h index 24010ec..a24663c 100644 --- a/src/Engine/Graphics/RenderPass/MeshProcessor.h +++ b/src/Engine/Graphics/RenderPass/MeshProcessor.h @@ -17,7 +17,7 @@ public: protected: PScene scene; Gfx::PGraphics graphics; - virtual Job processMeshBatch( + virtual void processMeshBatch( const MeshBatch& batch, // const PPrimitiveComponent primitiveComponent, const Gfx::PRenderPass& renderPass, diff --git a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp index c06303c..b28da6f 100644 --- a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp @@ -74,7 +74,7 @@ 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; + //std::cout << "Beginning renderPass" << std::endl; } void CmdBuffer::endRenderPass() @@ -82,7 +82,7 @@ void CmdBuffer::endRenderPass() std::unique_lock lock(handleLock); vkCmdEndRenderPass(handle); state = State::InsideBegin; - std::cout << "Ending renderPass" << std::endl; + //std::cout << "Ending renderPass" << std::endl; } void CmdBuffer::executeCommands(const Array& commands) diff --git a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp index c54466e..7d2b5fb 100644 --- a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp @@ -9,105 +9,105 @@ using namespace Seele; using namespace Seele::Vulkan; DescriptorLayout::DescriptorLayout(PGraphics graphics, const std::string& name) - : Gfx::DescriptorLayout(name) - , graphics(graphics) - , layoutHandle(VK_NULL_HANDLE) + : Gfx::DescriptorLayout(name) + , graphics(graphics) + , layoutHandle(VK_NULL_HANDLE) { } DescriptorLayout::~DescriptorLayout() { - if (layoutHandle != VK_NULL_HANDLE) - { - vkDestroyDescriptorSetLayout(graphics->getDevice(), layoutHandle, nullptr); - } + if (layoutHandle != VK_NULL_HANDLE) + { + vkDestroyDescriptorSetLayout(graphics->getDevice(), layoutHandle, nullptr); + } } void DescriptorLayout::create() { - if (layoutHandle != VK_NULL_HANDLE) - { - return; - } - bindings.resize(descriptorBindings.size()); - for (size_t i = 0; i < descriptorBindings.size(); ++i) - { - VkDescriptorSetLayoutBinding &binding = bindings[i]; - const Gfx::DescriptorBinding &rhiBinding = descriptorBindings[i]; - binding.binding = rhiBinding.binding; - binding.descriptorCount = rhiBinding.descriptorCount; - binding.descriptorType = cast(rhiBinding.descriptorType); - binding.stageFlags = rhiBinding.shaderStages; - binding.pImmutableSamplers = nullptr; - } - VkDescriptorSetLayoutCreateInfo createInfo = - init::DescriptorSetLayoutCreateInfo(bindings.data(), (uint32)bindings.size()); - VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle)); + if (layoutHandle != VK_NULL_HANDLE) + { + return; + } + bindings.resize(descriptorBindings.size()); + for (size_t i = 0; i < descriptorBindings.size(); ++i) + { + VkDescriptorSetLayoutBinding &binding = bindings[i]; + const Gfx::DescriptorBinding &rhiBinding = descriptorBindings[i]; + binding.binding = rhiBinding.binding; + binding.descriptorCount = rhiBinding.descriptorCount; + binding.descriptorType = cast(rhiBinding.descriptorType); + binding.stageFlags = rhiBinding.shaderStages; + binding.pImmutableSamplers = nullptr; + } + VkDescriptorSetLayoutCreateInfo createInfo = + init::DescriptorSetLayoutCreateInfo(bindings.data(), (uint32)bindings.size()); + VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle)); - allocator = new DescriptorAllocator(graphics, *this); + allocator = new DescriptorAllocator(graphics, *this); - boost::crc_32_type result; - result.process_bytes(bindings.data(), sizeof(VkDescriptorSetLayoutBinding) * bindings.size()); - hash = result.checksum(); + boost::crc_32_type result; + result.process_bytes(bindings.data(), sizeof(VkDescriptorSetLayoutBinding) * bindings.size()); + hash = result.checksum(); } PipelineLayout::~PipelineLayout() { - if (layoutHandle != VK_NULL_HANDLE) - { - vkDestroyPipelineLayout(graphics->getDevice(), layoutHandle, nullptr); - } + if (layoutHandle != VK_NULL_HANDLE) + { + vkDestroyPipelineLayout(graphics->getDevice(), layoutHandle, nullptr); + } } static Map layoutCache; void PipelineLayout::create() { - vulkanDescriptorLayouts.resize(descriptorSetLayouts.size()); - for (size_t i = 0; i < descriptorSetLayouts.size(); ++i) - { - // There could be unused descriptor set indices - if(descriptorSetLayouts[i] == nullptr) - { - vulkanDescriptorLayouts[i] = VK_NULL_HANDLE; - continue; - } - PDescriptorLayout layout = descriptorSetLayouts[i].cast(); - layout->create(); - vulkanDescriptorLayouts[i] = layout->getHandle(); - } + vulkanDescriptorLayouts.resize(descriptorSetLayouts.size()); + for (size_t i = 0; i < descriptorSetLayouts.size(); ++i) + { + // There could be unused descriptor set indices + if(descriptorSetLayouts[i] == nullptr) + { + vulkanDescriptorLayouts[i] = VK_NULL_HANDLE; + continue; + } + PDescriptorLayout layout = descriptorSetLayouts[i].cast(); + layout->create(); + vulkanDescriptorLayouts[i] = layout->getHandle(); + } - VkPipelineLayoutCreateInfo createInfo = - init::PipelineLayoutCreateInfo(vulkanDescriptorLayouts.data(), (uint32)vulkanDescriptorLayouts.size()); - Array vkPushConstants(pushConstants.size()); - for (size_t i = 0; i < pushConstants.size(); i++) - { - vkPushConstants[i].offset = pushConstants[i].offset; - vkPushConstants[i].size = pushConstants[i].size; - vkPushConstants[i].stageFlags = (VkShaderStageFlagBits)pushConstants[i].stageFlags; - } - createInfo.pushConstantRangeCount = (uint32)vkPushConstants.size(); - createInfo.pPushConstantRanges = vkPushConstants.data(); + VkPipelineLayoutCreateInfo createInfo = + init::PipelineLayoutCreateInfo(vulkanDescriptorLayouts.data(), (uint32)vulkanDescriptorLayouts.size()); + Array vkPushConstants(pushConstants.size()); + for (size_t i = 0; i < pushConstants.size(); i++) + { + vkPushConstants[i].offset = pushConstants[i].offset; + vkPushConstants[i].size = pushConstants[i].size; + vkPushConstants[i].stageFlags = (VkShaderStageFlagBits)pushConstants[i].stageFlags; + } + createInfo.pushConstantRangeCount = (uint32)vkPushConstants.size(); + createInfo.pPushConstantRanges = vkPushConstants.data(); - boost::crc_32_type result; - result.process_bytes(createInfo.pPushConstantRanges, sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount); - result.process_bytes(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount); - layoutHash = result.checksum(); + boost::crc_32_type result; + result.process_bytes(createInfo.pPushConstantRanges, sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount); + result.process_bytes(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount); + layoutHash = result.checksum(); - if(layoutCache[layoutHash] != VK_NULL_HANDLE) - { - layoutHandle = layoutCache[layoutHash]; - return; - } + if(layoutCache[layoutHash] != VK_NULL_HANDLE) + { + layoutHandle = layoutCache[layoutHash]; + return; + } - VK_CHECK(vkCreatePipelineLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle)); - layoutCache[layoutHash] = layoutHandle; + VK_CHECK(vkCreatePipelineLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle)); + layoutCache[layoutHash] = layoutHandle; } void PipelineLayout::reset() { - vkDestroyPipelineLayout(graphics->getDevice(), layoutHandle, nullptr); - descriptorSetLayouts.clear(); - pushConstants.clear(); + vkDestroyPipelineLayout(graphics->getDevice(), layoutHandle, nullptr); + descriptorSetLayouts.clear(); + pushConstants.clear(); } DescriptorSet::~DescriptorSet() @@ -116,206 +116,219 @@ DescriptorSet::~DescriptorSet() void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) { - PUniformBuffer vulkanBuffer = uniformBuffer.cast(); - UniformBuffer* cachedBuffer = reinterpret_cast(cachedData[binding]); - if(vulkanBuffer->isDataEquals(cachedBuffer)) - { - std::cout << "uniform data equal, skip" << std::endl; - return; - } - bufferInfos.add(init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize())); + PUniformBuffer vulkanBuffer = uniformBuffer.cast(); + UniformBuffer* cachedBuffer = reinterpret_cast(cachedData[binding]); + if(vulkanBuffer->isDataEquals(cachedBuffer)) + { + std::cout << "uniform data equal, skip" << std::endl; + return; + } + bufferInfos.add(init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize())); - VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, binding, &bufferInfos.back()); - writeDescriptors.add(writeDescriptor); + VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, binding, &bufferInfos.back()); + writeDescriptors.add(writeDescriptor); - cachedData[binding] = new UniformBuffer(*vulkanBuffer.getHandle()); + cachedData[binding] = new UniformBuffer(*vulkanBuffer.getHandle()); } void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer) { - PStructuredBuffer vulkanBuffer = uniformBuffer.cast(); - StructuredBuffer* cachedBuffer = reinterpret_cast(cachedData[binding]); - if(vulkanBuffer.getHandle() == cachedBuffer) - { - return; - } - bufferInfos.add(init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize())); + PStructuredBuffer vulkanBuffer = uniformBuffer.cast(); + StructuredBuffer* cachedBuffer = reinterpret_cast(cachedData[binding]); + if(vulkanBuffer.getHandle() == cachedBuffer) + { + return; + } + bufferInfos.add(init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize())); - VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, binding, &bufferInfos.back()); - writeDescriptors.add(writeDescriptor); + VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, binding, &bufferInfos.back()); + writeDescriptors.add(writeDescriptor); - cachedData[binding] = vulkanBuffer.getHandle(); + cachedData[binding] = vulkanBuffer.getHandle(); } void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSamplerState samplerState) { - PSamplerState vulkanSampler = samplerState.cast(); - SamplerState* cachedSampler = reinterpret_cast(cachedData[binding]); - if(vulkanSampler.getHandle() == cachedSampler) - { - return; - } - VkDescriptorImageInfo imageInfo = - init::DescriptorImageInfo( - vulkanSampler->sampler, - VK_NULL_HANDLE, - VK_IMAGE_LAYOUT_UNDEFINED); - imageInfos.add(imageInfo); + PSamplerState vulkanSampler = samplerState.cast(); + SamplerState* cachedSampler = reinterpret_cast(cachedData[binding]); + if(vulkanSampler.getHandle() == cachedSampler) + { + return; + } + VkDescriptorImageInfo imageInfo = + init::DescriptorImageInfo( + vulkanSampler->sampler, + VK_NULL_HANDLE, + VK_IMAGE_LAYOUT_UNDEFINED); + imageInfos.add(imageInfo); - VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_SAMPLER, binding, &imageInfos.back()); - writeDescriptors.add(writeDescriptor); + VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_SAMPLER, binding, &imageInfos.back()); + writeDescriptors.add(writeDescriptor); - cachedData[binding] = vulkanSampler.getHandle(); + cachedData[binding] = vulkanSampler.getHandle(); } void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState samplerState) { - TextureHandle* vulkanTexture = TextureBase::cast(texture); - TextureHandle* cachedTexture = reinterpret_cast(cachedData[binding]); - if(vulkanTexture == cachedTexture) - { - return; - } - //It is assumed that the image is in the correct layout - VkDescriptorImageInfo imageInfo = - init::DescriptorImageInfo( - VK_NULL_HANDLE, - vulkanTexture->getView(), - cast(vulkanTexture->getLayout())); - if (samplerState != nullptr) - { - PSamplerState vulkanSampler = samplerState.cast(); - imageInfo.sampler = vulkanSampler->sampler; - } - imageInfos.add(imageInfo); - VkWriteDescriptorSet writeDescriptor = - init::WriteDescriptorSet( - setHandle, - samplerState != nullptr ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - binding, - &imageInfos.back()); - if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) - { - writeDescriptor.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - } - writeDescriptors.add(writeDescriptor); + TextureHandle* vulkanTexture = TextureBase::cast(texture); + TextureHandle* cachedTexture = reinterpret_cast(cachedData[binding]); + if(vulkanTexture == cachedTexture) + { + return; + } + //It is assumed that the image is in the correct layout + VkDescriptorImageInfo imageInfo = + init::DescriptorImageInfo( + VK_NULL_HANDLE, + vulkanTexture->getView(), + cast(vulkanTexture->getLayout())); + if (samplerState != nullptr) + { + PSamplerState vulkanSampler = samplerState.cast(); + imageInfo.sampler = vulkanSampler->sampler; + } + imageInfos.add(imageInfo); + VkWriteDescriptorSet writeDescriptor = + init::WriteDescriptorSet( + setHandle, + samplerState != nullptr ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + binding, + &imageInfos.back()); + if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) + { + writeDescriptor.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + } + writeDescriptors.add(writeDescriptor); - cachedData[binding] = vulkanTexture; + cachedData[binding] = vulkanTexture; } bool DescriptorSet::operator<(Gfx::PDescriptorSet other) { - PDescriptorSet otherSet = other.cast(); - return this < otherSet.getHandle(); + PDescriptorSet otherSet = other.cast(); + return this < otherSet.getHandle(); } uint32 DescriptorSet::getSetIndex() const { - return owner->getLayout().getSetIndex(); + return owner->getLayout().getSetIndex(); } void DescriptorSet::writeChanges() { - if (writeDescriptors.size() > 0) - { - if(isCurrentlyBound()) - { - std::cout << "Descriptor currently bound, allocate a new one instead" << std::endl; - assert(!isCurrentlyBound()); - } - vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr); - writeDescriptors.clear(); - imageInfos.clear(); - bufferInfos.clear(); - } + if (writeDescriptors.size() > 0) + { + if(isCurrentlyBound()) + { + std::cout << "Descriptor currently bound, allocate a new one instead" << std::endl; + assert(!isCurrentlyBound()); + } + vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr); + writeDescriptors.clear(); + imageInfos.clear(); + bufferInfos.clear(); + } } DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout &layout) - : graphics(graphics) - , layout(layout) + : graphics(graphics) + , layout(layout) { - for(uint32 i = 0; i < cachedHandles.size(); ++i) - { - cachedHandles[i] = nullptr; - } + for(uint32 i = 0; i < cachedHandles.size(); ++i) + { + cachedHandles[i] = nullptr; + } - uint32 perTypeSizes[VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT]; // TODO: FIX ENUM - std::memset(perTypeSizes, 0, sizeof(perTypeSizes)); - for (uint32 i = 0; i < layout.getBindings().size(); ++i) - { - auto &binding = layout.getBindings()[i]; - int typeIndex = binding.descriptorType; - perTypeSizes[typeIndex] += 256; - } - Array poolSizes; - for (uint32 i = 0; i < VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; ++i) - { - if (perTypeSizes[i] > 0) - { - VkDescriptorPoolSize size; - size.descriptorCount = perTypeSizes[i]; - size.type = (VkDescriptorType)i; - poolSizes.add(size); - } - } - VkDescriptorPoolCreateInfo createInfo - = init::DescriptorPoolCreateInfo( - (uint32)poolSizes.size(), - poolSizes.data(), - maxSets * Gfx::numFramesBuffered); - VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle)); + uint32 perTypeSizes[VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT]; // TODO: FIX ENUM + std::memset(perTypeSizes, 0, sizeof(perTypeSizes)); + for (uint32 i = 0; i < layout.getBindings().size(); ++i) + { + auto &binding = layout.getBindings()[i]; + int typeIndex = binding.descriptorType; + perTypeSizes[typeIndex] += 256; + } + Array poolSizes; + for (uint32 i = 0; i < VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; ++i) + { + if (perTypeSizes[i] > 0) + { + VkDescriptorPoolSize size; + size.descriptorCount = perTypeSizes[i]; + size.type = (VkDescriptorType)i; + poolSizes.add(size); + } + } + VkDescriptorPoolCreateInfo createInfo + = init::DescriptorPoolCreateInfo( + (uint32)poolSizes.size(), + poolSizes.data(), + maxSets * Gfx::numFramesBuffered); + VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle)); } DescriptorAllocator::~DescriptorAllocator() { - vkDestroyDescriptorPool(graphics->getDevice(), poolHandle, nullptr); - graphics = nullptr; + vkDestroyDescriptorPool(graphics->getDevice(), poolHandle, nullptr); + graphics = nullptr; + if(nextAlloc) + { + delete nextAlloc; + } } void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet) { - VkDescriptorSetLayout layoutHandle = layout.getHandle(); - VkDescriptorSetAllocateInfo allocInfo = - init::DescriptorSetAllocateInfo(poolHandle, &layoutHandle, 1); + VkDescriptorSetLayout layoutHandle = layout.getHandle(); + VkDescriptorSetAllocateInfo allocInfo = + init::DescriptorSetAllocateInfo(poolHandle, &layoutHandle, 1); - for(uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex) - { - if(cachedHandles[setIndex] == nullptr) - { - cachedHandles[setIndex] = new DescriptorSet(graphics, this); - } - if(cachedHandles[setIndex]->isCurrentlyBound() || cachedHandles[setIndex]->isCurrentlyInUse()) - { - // Currently in use, skip - continue; - } - if(cachedHandles[setIndex]->getHandle() == VK_NULL_HANDLE) - { - //If it hasnt been initialized, allocate it - VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &cachedHandles[setIndex]->setHandle)); - } - cachedHandles[setIndex]->allocate(); - descriptorSet = cachedHandles[setIndex]; - - PDescriptorSet vulkanSet = descriptorSet.cast(); - vulkanSet->cachedData.resize(layout.bindings.size()); - // Not really pretty, but this way the set knows which ones are valid - std::memset(vulkanSet->cachedData.data(), 0, sizeof(void*) * vulkanSet->cachedData.size()); - - //Found set, stop searching - return; - } - throw std::logic_error("Out of descriptor sets"); + for(uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex) + { + if(cachedHandles[setIndex] == nullptr) + { + cachedHandles[setIndex] = new DescriptorSet(graphics, this); + } + if(cachedHandles[setIndex]->isCurrentlyBound() || cachedHandles[setIndex]->isCurrentlyInUse()) + { + // Currently in use, skip + continue; + } + if(cachedHandles[setIndex]->getHandle() == VK_NULL_HANDLE) + { + //If it hasnt been initialized, allocate it + VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &cachedHandles[setIndex]->setHandle)); + } + cachedHandles[setIndex]->allocate(); + descriptorSet = cachedHandles[setIndex]; + + PDescriptorSet vulkanSet = descriptorSet.cast(); + vulkanSet->cachedData.resize(layout.bindings.size()); + // Not really pretty, but this way the set knows which ones are valid + std::memset(vulkanSet->cachedData.data(), 0, sizeof(void*) * vulkanSet->cachedData.size()); + + //Found set, stop searching + return; + } + if(nextAlloc == nullptr) + { + nextAlloc = new DescriptorAllocator(graphics, layout); + } + nextAlloc->allocateDescriptorSet(descriptorSet); + //throw std::logic_error("Out of descriptor sets"); } void DescriptorAllocator::reset() { - for(uint32 i = 0; i < cachedHandles.size(); ++i) - { - if(cachedHandles[i] == nullptr) - { - return; - } - cachedHandles[i]->free(); - } + for(uint32 i = 0; i < cachedHandles.size(); ++i) + { + if(cachedHandles[i] == nullptr) + { + return; + } + cachedHandles[i]->free(); + } + if(nextAlloc != nullptr) + { + nextAlloc->reset(); + } } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h index 0272f82..a13b489 100644 --- a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h +++ b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h @@ -145,6 +145,7 @@ private: const static int maxSets = 64; StaticArray cachedHandles; VkDescriptorPool poolHandle; + DescriptorAllocator* nextAlloc = nullptr; }; DEFINE_REF(DescriptorAllocator) } // namespace Vulkan diff --git a/src/Engine/ThreadPool.cpp b/src/Engine/ThreadPool.cpp index 1a8f232..44e77e1 100644 --- a/src/Engine/ThreadPool.cpp +++ b/src/Engine/ThreadPool.cpp @@ -3,6 +3,8 @@ using namespace Seele; +std::atomic_uint64_t Seele::globalCounter; + Event::Event() : flag(new std::atomic_bool()) { @@ -54,7 +56,6 @@ ThreadPool::~ThreadPool() void ThreadPool::enqueueWaiting(Event &event, Promise* job) { assert(!job->done()); - assert(job->schedulable); if(event == nullptr) { std::unique_lock lock(jobQueueLock); @@ -72,8 +73,7 @@ void ThreadPool::enqueueWaiting(Event &event, Promise* job) void ThreadPool::enqueueWaiting(Event &event, MainPromise* job) { assert(!job->done()); - assert(job->schedulable); - if(event == nullptr) + if(event == nullptr || event) { std::unique_lock lock(mainJobLock); //std::cout << "Queueing job " << job->finishedEvent.name << std::endl; @@ -98,6 +98,7 @@ void ThreadPool::notify(Event &event) { //assert(job.id != -1ull); //std::cout << "Waking up " << job->finishedEvent.name << std::endl; + job->state = Promise::State::SCHEDULED; jobQueue.add(job); jobQueueCV.notify_one(); } @@ -111,6 +112,7 @@ void ThreadPool::notify(Event &event) { //assert(job.id != -1ull); //std::cout << "Waking up main " << job->finishedEvent.name << std::endl; + job->state = MainPromise::State::SCHEDULED; mainJobs.add(job); mainJobCV.notify_one(); } diff --git a/src/Engine/ThreadPool.h b/src/Engine/ThreadPool.h index af261eb..acc1751 100644 --- a/src/Engine/ThreadPool.h +++ b/src/Engine/ThreadPool.h @@ -45,12 +45,20 @@ private: friend class ThreadPool; }; -static std::atomic_uint64_t globalCounter; +extern std::atomic_uint64_t globalCounter; template struct JobBase; template struct JobPromiseBase { + enum class State + { + READY, + WAITING, + SCHEDULED, + EXECUTING, + DONE + }; JobPromiseBase() { handle = std::coroutine_handle>::from_promise(*this); @@ -71,11 +79,12 @@ struct JobPromiseBase void resume() { std::unique_lock lock(promiseLock); - if(handle && !handle.done()) + if(!handle || handle.done() || executing()) { - handle.resume(); - schedulable = true; + return; } + state = State::EXECUTING; + handle.resume(); } void setContinuation(JobPromiseBase* cont) { @@ -88,9 +97,26 @@ struct JobPromiseBase { return handle.done(); } + bool scheduled() + { + return state == State::SCHEDULED; + } + bool waiting() + { + return state == State::WAITING; + } + bool executing() + { + return state == State::EXECUTING; + } + bool ready() + { + return state == State::READY; + } void raise() { std::unique_lock lock(promiseLock); + state = State::DONE; finishedEvent.raise(); } void reset() @@ -100,22 +126,23 @@ struct JobPromiseBase } void enqueue(Event& event) { - if(!handle || handle.done() || !schedulable) + // no need to lock here, as it is only called while executing, where the lock is already held + if(!handle || handle.done() || waiting() || scheduled()) { return; } + state = State::WAITING; getGlobalThreadPool().enqueueWaiting(event, this); - schedulable = false; } void schedule() { std::unique_lock lock(promiseLock); - if(!handle || handle.done() || !schedulable) + if(!handle || done() || !ready()) { return; } + state = (precondition == nullptr) ? State::SCHEDULED : State::WAITING; getGlobalThreadPool().enqueueWaiting(precondition, this); - schedulable = false; } std::mutex promiseLock; @@ -124,7 +151,7 @@ struct JobPromiseBase uint64 id; Event finishedEvent; Event precondition = nullptr; - bool schedulable = true; + State state = State::READY; }; template @@ -176,6 +203,7 @@ public: } Event operator co_await() { + promise->schedule(); return promise->finishedEvent; } static JobBase all() = delete; diff --git a/src/Engine/Window/SceneView.cpp b/src/Engine/Window/SceneView.cpp index a742ce6..f16135a 100644 --- a/src/Engine/Window/SceneView.cpp +++ b/src/Engine/Window/SceneView.cpp @@ -18,29 +18,29 @@ Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const Viewpo { scene = new Scene(graphics); scene->addActor(activeCamera); - /*AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Body_Diffuse.png"); - AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Body_Lightmap.png"); - AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Face_Diffuse.png"); - AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Hair_Diffuse.png"); - AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Hair_Lightmap.png"); - AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Tex_FaceLightmap.png"); - AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Ayaka.fbx"); - PPrimitiveComponent ayaka = new PrimitiveComponent(AssetRegistry::findMesh("Ayaka")); - ayaka->addWorldTranslation(Vector(0, 0, 0)); - ayaka->setWorldScale(Vector(10, 10, 10)); - scene->addPrimitiveComponent(ayaka);*/ + AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Body_Diffuse.png"); + AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Body_Lightmap.png"); + AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Face_Diffuse.png"); + AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Hair_Diffuse.png"); + AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Hair_Lightmap.png"); + AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Tex_FaceLightmap.png"); + AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Ayaka.fbx"); + AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ely\\Ely.fbx"); + AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Cube\\cube.obj"); + AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Plane\\plane.fbx"); + srand(time(NULL)); + for(uint32 i = 0; i < 100; ++i) + { + PPrimitiveComponent ayaka = new PrimitiveComponent(AssetRegistry::findMesh("Ayaka")); + ayaka->addWorldTranslation(Vector(((float)rand() / RAND_MAX) * 100, 0, ((float)rand()/RAND_MAX) * 100)); + ayaka->setWorldScale(Vector(10, 10, 10)); + scene->addPrimitiveComponent(ayaka); + } - AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Ely\\Ely.fbx"); - AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Cube\\cube.obj"); - AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Plane\\plane.fbx"); PPrimitiveComponent plane = new PrimitiveComponent(AssetRegistry::findMesh("plane")); plane->setWorldScale(Vector(100, 100, 100)); - PPrimitiveComponent arissa = new PrimitiveComponent(AssetRegistry::findMesh("Ely")); - arissa->addWorldTranslation(Vector(0, 0, 100)); - arissa->setWorldScale(Vector(0.1f, 0.1f, 0.1f)); scene->addPrimitiveComponent(plane); - scene->addPrimitiveComponent(arissa); - + PRenderGraphResources resources = new RenderGraphResources(); depthPrepass.setResources(resources); lightCullingPass.setResources(resources); diff --git a/src/Engine/Window/View.cpp b/src/Engine/Window/View.cpp index 12a0945..be8fa24 100644 --- a/src/Engine/Window/View.cpp +++ b/src/Engine/Window/View.cpp @@ -8,7 +8,7 @@ View::View(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &vi : graphics(graphics) , owner(window) , name(name) - , renderFinishedEvent(name + "RenderFinished") + , renderFinishedEvent(std::format("{}RenderFinished", name)) { viewport = graphics->createViewport(owner->getGfxHandle(), viewportInfo); } diff --git a/src/Engine/main.cpp b/src/Engine/main.cpp index ad352da..87a4b3f 100644 --- a/src/Engine/main.cpp +++ b/src/Engine/main.cpp @@ -9,7 +9,7 @@ using namespace Seele; int main() { PWindowManager windowManager = new WindowManager(); - AssetRegistry::init("D:\\Private\\Programming\\C++\\TestSeeleProject"); + AssetRegistry::init("C:\\Users\\Dynamitos\\TestSeeleProject"); WindowCreateInfo mainWindowInfo; mainWindowInfo.title = "SeeleEngine"; mainWindowInfo.width = 1280; @@ -34,9 +34,9 @@ int main() //PInspectorView inspectorView = new InspectorView(windowManager->getGraphics(), window, inspectorViewInfo); //window->addView(inspectorView); sceneView->setFocused(); - { - window->render(); - } + + window->render(); + getGlobalThreadPool().threadLoop(true); return 0; } \ No newline at end of file