From 41710220ec55a726fc51654d0e6b30aae6b3c03d Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Fri, 30 Oct 2020 18:45:35 +0100 Subject: [PATCH] Improving performance, but breaking vertex buffers --- .vscode/settings.json | 2 +- CMakeLists.txt | 3 +- cmake/FindAssimp.cmake | 12 +- src/Engine/Containers/Map.h | 2 +- src/Engine/Graphics/GraphicsResources.h | 7 +- src/Engine/Graphics/RenderPass/BasePass.cpp | 14 ++- src/Engine/Graphics/RenderPass/BasePass.h | 1 + src/Engine/Graphics/SceneView.cpp | 1 - .../Graphics/Vulkan/VulkanAllocator.cpp | 11 +- src/Engine/Graphics/Vulkan/VulkanAllocator.h | 10 ++ src/Engine/Graphics/Vulkan/VulkanBuffer.cpp | 9 +- .../Graphics/Vulkan/VulkanCommandBuffer.cpp | 5 + .../Graphics/Vulkan/VulkanCommandBuffer.h | 1 + .../Graphics/Vulkan/VulkanDescriptorSets.cpp | 8 -- .../Graphics/Vulkan/VulkanDescriptorSets.h | 2 - src/Engine/Graphics/Vulkan/VulkanGraphics.cpp | 3 +- .../Graphics/Vulkan/VulkanPipelineCache.cpp | 105 ++++++++++++++---- .../Graphics/Vulkan/VulkanPipelineCache.h | 1 + src/Engine/Graphics/Vulkan/VulkanShader.cpp | 10 ++ src/Engine/Graphics/Vulkan/VulkanShader.h | 2 + src/Engine/Graphics/Vulkan/VulkanViewport.cpp | 1 - src/Engine/Material/MaterialAsset.cpp | 2 - src/Engine/MinimalEngine.h | 4 +- src/Engine/main.cpp | 2 +- test/Engine/Containers/List.cpp | 8 +- 25 files changed, 164 insertions(+), 62 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 954fc30..745b8e1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -107,7 +107,7 @@ "scoped_allocator": "cpp", "stack": "cpp" }, - "cmake.generator": "Ninja", + "cmake.generator": "Visual Studio 16 2019", "cmake.skipConfigureIfCachePresent": false, "cmake.configureArgs": [ "-Wno-dev" diff --git a/CMakeLists.txt b/CMakeLists.txt index 574755b..a5a091d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,7 +44,7 @@ find_package(Threads REQUIRED) find_package(assimp REQUIRED) find_package(JSON REQUIRED) find_package(GLFW REQUIRED) -find_package(SPIRV REQUIRED) +#find_package(SPIRV REQUIRED) find_package(GLM REQUIRED) find_package(STB REQUIRED) find_package(SLang REQUIRED) @@ -113,4 +113,5 @@ add_custom_target(copy-runtime-files ALL COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SLANG_BINARY} $ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SLANG_GLSLANG} $ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GLFW_BINARY} $ + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ASSIMP_BINARY} $ DEPENDS SeeleEngine) \ No newline at end of file diff --git a/cmake/FindAssimp.cmake b/cmake/FindAssimp.cmake index 8527d0e..537ae50 100644 --- a/cmake/FindAssimp.cmake +++ b/cmake/FindAssimp.cmake @@ -30,6 +30,13 @@ if (WIN32) PATHS $ENV{PROGRAMFILES}/lib ${ASSIMP_ROOT}/lib/) + + find_file( + ASSIMP_BINARY + NAMES assimp-vc${MSVC_TOOLSET_VERSION}-mt${CMAKE_DEBUG_POSTFIX}.dll + PATHS + $ENV{PROGRAMFILES}/bin + ${ASSIMP_ROOT}/bin) else() # Find include files find_path( @@ -58,13 +65,14 @@ else() endif() # Handle REQUIRD argument, define *_FOUND variable -find_package_handle_standard_args(assimp DEFAULT_MSG ASSIMP_INCLUDE_DIR ASSIMP_LIBRARY) +find_package_handle_standard_args(assimp DEFAULT_MSG ASSIMP_INCLUDE_DIR ASSIMP_LIBRARY ASSIMP_BINARY) # Define GLFW_LIBRARIES and GLFW_INCLUDE_DIRS if (ASSIMP_FOUND) set(ASSIMP_LIBRARIES ${ASSIMP_LIBRARY}) set(ASSIMP_INCLUDE_DIRS ${ASSIMP_INCLUDE_DIR}) + set(ASSIMP_BINARIES ${ASSIMP_BINARY}) endif() # Hide some variables -mark_as_advanced(ASSIMP_INCLUDE_DIR ASSIMP_LIBRARY) \ No newline at end of file +mark_as_advanced(ASSIMP_INCLUDE_DIR ASSIMP_LIBRARY, ASSIMP_BINARY) \ No newline at end of file diff --git a/src/Engine/Containers/Map.h b/src/Engine/Containers/Map.h index 52c557b..470bb0a 100644 --- a/src/Engine/Containers/Map.h +++ b/src/Engine/Containers/Map.h @@ -264,8 +264,8 @@ public: { root = insert(root, key); _size++; + refreshIterators(); } - refreshIterators(); return root->pair.value; } Iterator find(const K &key) diff --git a/src/Engine/Graphics/GraphicsResources.h b/src/Engine/Graphics/GraphicsResources.h index 7a3973d..7e412e2 100644 --- a/src/Engine/Graphics/GraphicsResources.h +++ b/src/Engine/Graphics/GraphicsResources.h @@ -190,8 +190,6 @@ class DescriptorSet { public: virtual ~DescriptorSet() {} - virtual void beginFrame() = 0; - virtual void endFrame() = 0; virtual void writeChanges() = 0; virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0; virtual void updateBuffer(uint32 binding, PStructuredBuffer structuredBuffer) = 0; @@ -481,6 +479,7 @@ class RenderCommand public: RenderCommand(); virtual ~RenderCommand(); + virtual void begin() = 0; virtual void setViewport(Gfx::PViewport viewport) = 0; virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) = 0; virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0; @@ -586,7 +585,7 @@ class SwapchainAttachment : public RenderTargetAttachment { public: SwapchainAttachment(PWindow owner, - SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD, + SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_CLEAR, SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE, SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE) @@ -595,7 +594,7 @@ public: clear.color.float32[0] = 0.0f; clear.color.float32[1] = 0.0f; clear.color.float32[2] = 0.0f; - clear.color.float32[3] = 0.0f; + clear.color.float32[3] = 1.0f; componentFlags = SE_COLOR_COMPONENT_R_BIT | SE_COLOR_COMPONENT_G_BIT | SE_COLOR_COMPONENT_B_BIT | SE_COLOR_COMPONENT_A_BIT; } virtual PTexture2D getTexture() override diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index a7d51be..d6b90ee 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -41,7 +41,18 @@ void BasePassMeshProcessor::addMeshBatch( descriptorSet->writeChanges(); cachedPrimitiveSets.add(descriptorSet); } - Gfx::PRenderCommand renderCommand = graphics->createRenderCommand(); + Gfx::PRenderCommand renderCommand; + if (cachedCommandBuffers.size() > 0) + { + renderCommand = cachedCommandBuffers.back(); + cachedCommandBuffers.pop(); + renderCommand->begin(); + } + else + { + renderCommand = graphics->createRenderCommand(); + renderCommand->begin(); + } renderCommand->setViewport(target); for(uint32 i = 0; i < batch.elements.size(); ++i) { @@ -72,6 +83,7 @@ Array BasePassMeshProcessor::getRenderCommands() void BasePassMeshProcessor::clearCommands() { + cachedCommandBuffers = renderCommands; renderCommands.clear(); cachedPrimitiveSets.clear(); cachedPrimitiveIndex = 0; diff --git a/src/Engine/Graphics/RenderPass/BasePass.h b/src/Engine/Graphics/RenderPass/BasePass.h index d53b43e..307aad3 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.h +++ b/src/Engine/Graphics/RenderPass/BasePass.h @@ -22,6 +22,7 @@ public: void clearCommands(); private: Array renderCommands; + Array cachedCommandBuffers; Array cachedPrimitiveSets; uint32 cachedPrimitiveIndex; Gfx::PViewport target; diff --git a/src/Engine/Graphics/SceneView.cpp b/src/Engine/Graphics/SceneView.cpp index c41fec7..853faae 100644 --- a/src/Engine/Graphics/SceneView.cpp +++ b/src/Engine/Graphics/SceneView.cpp @@ -23,6 +23,5 @@ Seele::SceneView::~SceneView() void SceneView::keyCallback(KeyCode code, KeyAction action, KeyModifier modifier) { - std::cout << "Key callback " << (uint32)code << std::endl; activeCamera->getCameraComponent()->moveOrigin(1); } diff --git a/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp b/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp index 3f2b954..7ece006 100644 --- a/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp @@ -286,21 +286,22 @@ void StagingManager::clearPending() PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageFlags usage, bool bCPURead) { - std::unique_lock l(lock); for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it) { auto freeBuffer = *it; - if (freeBuffer->allocation->getSize() == size && freeBuffer->allocation->isReadable() == bCPURead) + if (freeBuffer->getSize() == size && freeBuffer->isReadable() == bCPURead && freeBuffer->usage == usage) { + std::cout << "Reusing staging buffer" << std::endl; activeBuffers.add(freeBuffer.getHandle()); freeBuffers.remove(it, false); return freeBuffer; } } - + std::cout << "Creating new stagingbuffer" << std::endl; PStagingBuffer stagingBuffer = new StagingBuffer(); VkBufferCreateInfo stagingBufferCreateInfo = init::BufferCreateInfo(usage, size); + stagingBufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; VkDevice vulkanDevice = graphics->getDevice(); VK_CHECK(vkCreateBuffer(vulkanDevice, &stagingBufferCreateInfo, nullptr, &stagingBuffer->buffer)); @@ -319,9 +320,11 @@ PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageF memReqs.memoryRequirements.alignment = (16 > memReqs.memoryRequirements.alignment) ? 16 : memReqs.memoryRequirements.alignment; - + stagingBuffer->allocation = allocator->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | (bCPURead ? VK_MEMORY_PROPERTY_HOST_COHERENT_BIT : VK_MEMORY_PROPERTY_HOST_CACHED_BIT), stagingBuffer->buffer); stagingBuffer->bReadable = bCPURead; + stagingBuffer->size = size; + stagingBuffer->usage = usage; vkBindBufferMemory(graphics->getDevice(), stagingBuffer->buffer, stagingBuffer->getMemoryHandle(), stagingBuffer->getOffset()); activeBuffers.add(stagingBuffer.getHandle()); diff --git a/src/Engine/Graphics/Vulkan/VulkanAllocator.h b/src/Engine/Graphics/Vulkan/VulkanAllocator.h index 9bbc435..b924cf8 100644 --- a/src/Engine/Graphics/Vulkan/VulkanAllocator.h +++ b/src/Engine/Graphics/Vulkan/VulkanAllocator.h @@ -190,10 +190,20 @@ public: { return allocation->getOffset(); } + uint32 getSize() const + { + return size; + } + bool isReadable() const + { + return bReadable; + } private: PSubAllocation allocation; VkBuffer buffer; + uint32 size; + VkBufferUsageFlags usage; uint8 bReadable; friend class StagingManager; }; diff --git a/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp b/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp index 659ce23..fd75bbe 100644 --- a/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp @@ -19,8 +19,7 @@ static Map pendingBuffers; ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType) : graphics(graphics), currentBuffer(0), size(size), currentOwner(queueType) { - if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT || - usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT || + if (usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT || usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT || usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) { @@ -54,7 +53,7 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags u vkCreateBuffer(graphics->getDevice(), &info, nullptr, &buffers[i].buffer); bufferReqInfo.buffer = buffers[i].buffer; vkGetBufferMemoryRequirements2(graphics->getDevice(), &bufferReqInfo, &memRequirements); - buffers[i].allocation = graphics->getAllocator()->allocate(memRequirements, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, buffers[i].buffer); + buffers[i].allocation = graphics->getAllocator()->allocate(memRequirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, buffers[i].buffer); vkBindBufferMemory(graphics->getDevice(), buffers[i].buffer, buffers[i].allocation->getHandle(), buffers[i].allocation->getOffset()); } } @@ -169,7 +168,7 @@ void *ShaderBuffer::lock(bool bWriteOnly) pending.prevQueue = currentOwner; if (bWriteOnly) { - requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER); + //requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER); PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); data = stagingBuffer->getMappedPointer(); pending.stagingBuffer = stagingBuffer; @@ -236,7 +235,7 @@ void ShaderBuffer::unlock() region.size = size; vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion); } - requestOwnershipTransfer(pending.prevQueue); + //requestOwnershipTransfer(pending.prevQueue); graphics->getStagingManager()->releaseStagingBuffer(pending.stagingBuffer); } } diff --git a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp index 2ecb137..4623611 100644 --- a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp @@ -159,6 +159,11 @@ void SecondaryCmdBuffer::end() VK_CHECK(vkEndCommandBuffer(handle)); } +void SecondaryCmdBuffer::begin() +{ + begin(graphics->getGraphicsCommands()->getCommands()); +} + void SecondaryCmdBuffer::setViewport(Gfx::PViewport viewport) { VkViewport vp = viewport.cast()->getHandle(); diff --git a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h index 0f7f8e5..7620db4 100644 --- a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h +++ b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h @@ -77,6 +77,7 @@ public: virtual ~SecondaryCmdBuffer(); void begin(PCmdBuffer parent); void end(); + virtual void begin() override; virtual void setViewport(Gfx::PViewport viewport) override; virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override; virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet) override; diff --git a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp index b9678f4..dc44608 100644 --- a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp @@ -111,14 +111,6 @@ DescriptorSet::~DescriptorSet() { } -void DescriptorSet::beginFrame() -{ -} - -void DescriptorSet::endFrame() -{ -} - void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) { PUniformBuffer vulkanBuffer = uniformBuffer.cast(); diff --git a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h index fa406d6..ceca693 100644 --- a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h +++ b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h @@ -87,8 +87,6 @@ public: { } virtual ~DescriptorSet(); - virtual void beginFrame(); - virtual void endFrame(); virtual void writeChanges(); virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer); virtual void updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer); diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp b/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp index e9002e8..e55933a 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp @@ -30,7 +30,9 @@ Graphics::~Graphics() void Graphics::init(GraphicsInitializer initInfo) { initInstance(initInfo); +#if ENABLE_VALIDATION setupDebugCallback(); +#endif pickPhysicalDevice(); createDevice(initInfo); allocator = new Allocator(this); @@ -121,7 +123,6 @@ Gfx::PIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkD Gfx::PRenderCommand Graphics::createRenderCommand() { PSecondaryCmdBuffer cmdBuffer = getGraphicsCommands()->createSecondaryCmdBuffer(); - cmdBuffer->begin(getGraphicsCommands()->getCommands()); return cmdBuffer; } diff --git a/src/Engine/Graphics/Vulkan/VulkanPipelineCache.cpp b/src/Engine/Graphics/Vulkan/VulkanPipelineCache.cpp index 92d1b10..da27c45 100644 --- a/src/Engine/Graphics/Vulkan/VulkanPipelineCache.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanPipelineCache.cpp @@ -46,6 +46,26 @@ PipelineCache::~PipelineCache() vkDestroyPipelineCache(graphics->getDevice(), cache, nullptr); } +struct PipelineCreateHashStruct +{ + uint32 vertexHash; + uint32 controlHash; + uint32 evalHash; + uint32 geometryHash; + uint32 fragmentHash; + uint32 pipelineLayoutHash; + VkPipelineTessellationStateCreateInfo tess; + VkVertexInputAttributeDescription attribs[16]; + VkVertexInputBindingDescription bindings[16]; + VkPipelineInputAssemblyStateCreateInfo inputAssembly; + VkPipelineViewportStateCreateInfo viewport; + VkPipelineRasterizationStateCreateInfo rasterization; + VkPipelineMultisampleStateCreateInfo multisample; + VkPipelineDepthStencilStateCreateInfo depthStencil; + VkPipelineColorBlendAttachmentState blendAttachments[16]; + VkPipelineColorBlendStateCreateInfo blendState; +}; + PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo& gfxInfo) { VkGraphicsPipelineCreateInfo createInfo; @@ -58,6 +78,8 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo std::memset(&tessInfo, 0, sizeof(VkPipelineTessellationStateCreateInfo)); VkPipelineShaderStageCreateInfo stageInfos[5]; std::memset(stageInfos, 0, sizeof(stageInfos)); + PipelineCreateHashStruct hashStruct; + std::memset(&hashStruct, 0, sizeof(PipelineCreateHashStruct)); PVertexShader vertexShader = gfxInfo.vertexShader.cast(); VkPipelineShaderStageCreateInfo& vertInfo = stageInfos[createInfo.stageCount++]; @@ -65,6 +87,7 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo vertInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; vertInfo.module = vertexShader->getModuleHandle(); vertInfo.pName = vertexShader->getEntryPointName(); + hashStruct.vertexHash = vertexShader->getShaderHash(); if(gfxInfo.controlShader != nullptr) { @@ -88,6 +111,10 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo tessInfo.pNext = 0; tessInfo.flags = 0; tessInfo.patchControlPoints = control->getNumPatches(); + + hashStruct.controlHash = control->getShaderHash(); + hashStruct.evalHash = eval->getShaderHash(); + hashStruct.tess = tessInfo; } if(gfxInfo.geometryShader != nullptr) { @@ -98,6 +125,8 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo geometryInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT; geometryInfo.module = geometry->getModuleHandle(); geometryInfo.pName = geometry->getEntryPointName(); + + hashStruct.geometryHash = geometry->getShaderHash(); } if(gfxInfo.fragmentShader != nullptr) { @@ -108,6 +137,8 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo fragmentInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; fragmentInfo.module = fragment->getModuleHandle(); fragmentInfo.pName = fragment->getEntryPointName(); + + hashStruct.fragmentHash = fragment->getShaderHash(); } VkPipelineVertexInputStateCreateInfo vertexInput = init::PipelineVertexInputStateCreateInfo(); @@ -180,6 +211,9 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo currAttribute.offset = element.offset; } + std::memcpy(hashStruct.bindings, bindings.data(), bindings.size() * sizeof(VkVertexInputBindingDescription)); + std::memcpy(hashStruct.attribs, attributes.data(), attributes.size() * sizeof(VkVertexInputAttributeDescription)); + vertexInput.pVertexBindingDescriptions = bindings.data(); vertexInput.vertexBindingDescriptionCount = bindings.size(); vertexInput.pVertexAttributeDescriptions = attributes.data(); @@ -191,6 +225,7 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo 0, false ); + hashStruct.inputAssembly = assemblyInfo; VkPipelineViewportStateCreateInfo viewportInfo = init::PipelineViewportStateCreateInfo( @@ -198,7 +233,8 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo 1, 0 ); - + hashStruct.viewport = viewportInfo; + VkPipelineRasterizationStateCreateInfo rasterizationState = init::PipelineRasterizationStateCreateInfo( cast(gfxInfo.rasterizationState.polygonMode), @@ -214,19 +250,27 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo rasterizationState.lineWidth = gfxInfo.rasterizationState.lineWidth; rasterizationState.rasterizerDiscardEnable = gfxInfo.rasterizationState.rasterizerDiscardEnable; + hashStruct.rasterization = rasterizationState; + VkPipelineMultisampleStateCreateInfo multisampleState = - init::PipelineMultisampleStateCreateInfo((VkSampleCountFlagBits)gfxInfo.multisampleState.samples, 0); + init::PipelineMultisampleStateCreateInfo( + (VkSampleCountFlagBits)gfxInfo.multisampleState.samples, + 0); multisampleState.alphaToCoverageEnable = gfxInfo.multisampleState.alphaCoverageEnable; multisampleState.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable; multisampleState.minSampleShading = gfxInfo.multisampleState.minSampleShading; multisampleState.sampleShadingEnable = gfxInfo.multisampleState.sampleShadingEnable; + hashStruct.multisample = multisampleState; + VkPipelineDepthStencilStateCreateInfo depthStencilState = init::PipelineDepthStencilStateCreateInfo( gfxInfo.depthStencilState.depthTestEnable, gfxInfo.depthStencilState.depthWriteEnable, cast(gfxInfo.depthStencilState.depthCompareOp) ); + + hashStruct.depthStencil = depthStencilState; const auto& colorAttachments = gfxInfo.renderPass->getLayout()->colorAttachments; Array blendAttachments(colorAttachments.size()); @@ -242,6 +286,8 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo blendAttachment.srcAlphaBlendFactor = (VkBlendFactor)attachment.srcAlphaBlendFactor; blendAttachment.dstColorBlendFactor = (VkBlendFactor)attachment.dstColorBlendFactor; blendAttachment.srcColorBlendFactor = (VkBlendFactor)attachment.srcColorBlendFactor; + + hashStruct.blendAttachments[i] = blendAttachment; } VkPipelineColorBlendStateCreateInfo blendState = init::PipelineColorBlendStateCreateInfo( @@ -252,6 +298,9 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo blendState.logicOp = (VkLogicOp)gfxInfo.colorBlend.logicOp; std::memcpy(blendState.blendConstants, gfxInfo.colorBlend.blendConstants, sizeof(float)*4); + hashStruct.blendState = blendState; + hashStruct.blendState.pAttachments = nullptr; + uint32 numDynamicEnabled = 0; StaticArray dynamicEnabled; dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_VIEWPORT; @@ -265,27 +314,41 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo ); PPipelineLayout layout = gfxInfo.pipelineLayout.cast(); + hashStruct.pipelineLayoutHash = layout->getHash(); - createInfo.pStages = stageInfos; - createInfo.pVertexInputState = &vertexInput; - createInfo.pInputAssemblyState = &assemblyInfo; - createInfo.pTessellationState = &tessInfo; - createInfo.pViewportState = &viewportInfo; - createInfo.pRasterizationState = &rasterizationState; - createInfo.pMultisampleState = &multisampleState; - createInfo.pDepthStencilState = &depthStencilState; - createInfo.pColorBlendState = &blendState; - createInfo.pDynamicState = &dynamicState; - createInfo.renderPass = gfxInfo.renderPass.cast()->getHandle(); - createInfo.layout = layout->getHandle(); - createInfo.subpass = 0; - + boost::crc_32_type crc; + crc.process_bytes(&hashStruct, sizeof(PipelineCreateHashStruct)); + uint32 hash = crc.checksum(); VkPipeline pipelineHandle; - auto beginTime = std::chrono::high_resolution_clock::now(); - VK_CHECK(vkCreateGraphicsPipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle)); - auto endTime = std::chrono::high_resolution_clock::now(); - int64 delta = std::chrono::duration_cast(endTime - beginTime).count(); - //std::cout << "Gfx creation time: " << delta << std::endl; + + auto foundPipeline = createdPipelines.find(hash); + if (foundPipeline != createdPipelines.end()) + { + pipelineHandle = foundPipeline->value; + } + else + { + createInfo.pStages = stageInfos; + createInfo.pVertexInputState = &vertexInput; + createInfo.pInputAssemblyState = &assemblyInfo; + createInfo.pTessellationState = &tessInfo; + createInfo.pViewportState = &viewportInfo; + createInfo.pRasterizationState = &rasterizationState; + createInfo.pMultisampleState = &multisampleState; + createInfo.pDepthStencilState = &depthStencilState; + createInfo.pColorBlendState = &blendState; + createInfo.pDynamicState = &dynamicState; + createInfo.renderPass = gfxInfo.renderPass.cast()->getHandle(); + createInfo.layout = layout->getHandle(); + createInfo.subpass = 0; + + auto beginTime = std::chrono::high_resolution_clock::now(); + VK_CHECK(vkCreateGraphicsPipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle)); + auto endTime = std::chrono::high_resolution_clock::now(); + int64 delta = std::chrono::duration_cast(endTime - beginTime).count(); + createdPipelines[hash] = pipelineHandle; + std::cout << "Gfx creation time: " << delta << std::endl; + } PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout, gfxInfo); return result; diff --git a/src/Engine/Graphics/Vulkan/VulkanPipelineCache.h b/src/Engine/Graphics/Vulkan/VulkanPipelineCache.h index 21814ee..02724d3 100644 --- a/src/Engine/Graphics/Vulkan/VulkanPipelineCache.h +++ b/src/Engine/Graphics/Vulkan/VulkanPipelineCache.h @@ -15,6 +15,7 @@ private: VkPipelineCache cache; PGraphics graphics; std::string cacheFile; + Map createdPipelines; }; DEFINE_REF(PipelineCache); } // namespace Vulkan diff --git a/src/Engine/Graphics/Vulkan/VulkanShader.cpp b/src/Engine/Graphics/Vulkan/VulkanShader.cpp index a9b16f8..3207163 100644 --- a/src/Engine/Graphics/Vulkan/VulkanShader.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanShader.cpp @@ -29,6 +29,11 @@ Map Shader::getDescriptorLayouts() return descriptorSets; } +uint32 Seele::Vulkan::Shader::getShaderHash() const +{ + return hash; +} + static SlangStage getStageFromShaderType(ShaderType type) { switch (type) @@ -127,4 +132,9 @@ void Shader::create(const ShaderCreateInfo& createInfo) moduleInfo.codeSize = dataSize; moduleInfo.pCode = data; VK_CHECK(vkCreateShaderModule(graphics->getDevice(), &moduleInfo, nullptr, &module)); + + boost::crc_32_type result; + result.process_bytes(entryPointName.data(), entryPointName.size()); + result.process_bytes(data, dataSize); + hash = result.checksum(); } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanShader.h b/src/Engine/Graphics/Vulkan/VulkanShader.h index 2b3762f..008c733 100644 --- a/src/Engine/Graphics/Vulkan/VulkanShader.h +++ b/src/Engine/Graphics/Vulkan/VulkanShader.h @@ -26,6 +26,7 @@ public: return "main";//entryPointName.c_str(); } Map getDescriptorLayouts(); + uint32 getShaderHash() const; private: PGraphics graphics; Map descriptorSets; @@ -33,6 +34,7 @@ private: VkShaderStageFlags stage; ShaderType type; std::string entryPointName; + uint32 hash; }; DEFINE_REF(Shader); diff --git a/src/Engine/Graphics/Vulkan/VulkanViewport.cpp b/src/Engine/Graphics/Vulkan/VulkanViewport.cpp index 6a026c3..715060a 100644 --- a/src/Engine/Graphics/Vulkan/VulkanViewport.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanViewport.cpp @@ -11,7 +11,6 @@ using namespace Seele::Vulkan; void glfwKeyCallback(GLFWwindow* handle, int key, int scancode, int action, int modifier) { Window* window = (Window*)glfwGetWindowUserPointer(handle); - std::cout << "glfw callback: " << key << std::endl; window->keyCallback((KeyCode)key, (KeyAction)action, (KeyModifier)modifier); } diff --git a/src/Engine/Material/MaterialAsset.cpp b/src/Engine/Material/MaterialAsset.cpp index e694370..30f819e 100644 --- a/src/Engine/Material/MaterialAsset.cpp +++ b/src/Engine/Material/MaterialAsset.cpp @@ -23,12 +23,10 @@ MaterialAsset::~MaterialAsset() void MaterialAsset::beginFrame() { - descriptorSet->beginFrame(); } void MaterialAsset::endFrame() { - descriptorSet->endFrame(); } void MaterialAsset::updateDescriptorData() diff --git a/src/Engine/MinimalEngine.h b/src/Engine/MinimalEngine.h index a749b24..aebc2a8 100644 --- a/src/Engine/MinimalEngine.h +++ b/src/Engine/MinimalEngine.h @@ -38,7 +38,7 @@ public: std::scoped_lock lock(registeredObjectsLock); registeredObjects[ptr] = this; } - RefObject(const RefObject &rhs) + inline RefObject(const RefObject &rhs) : handle(rhs.handle), refCount(rhs.refCount) { } @@ -143,7 +143,7 @@ public: { object->addRef(); } - RefPtr(const RefPtr &other) + inline RefPtr(const RefPtr &other) : object(other.object) { if (object != nullptr) diff --git a/src/Engine/main.cpp b/src/Engine/main.cpp index d89a399..7205ec7 100644 --- a/src/Engine/main.cpp +++ b/src/Engine/main.cpp @@ -20,12 +20,12 @@ int main() sceneViewInfo.offsetX = 0; sceneViewInfo.offsetY = 0; PSceneView sceneView = new SceneView(core.getWindowManager()->getGraphics(), window, sceneViewInfo); - sceneView->applyArea(URect(1280/2, 720/2, 10, 10)); window->addView(sceneView); sceneView->setFocused(); AssetRegistry::init("D:\\Private\\Programming\\C++\\TestSeeleProject"); AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Arissa\\Arissa.fbx"); PPrimitiveComponent arissa = new PrimitiveComponent(AssetRegistry::findMesh("Arissa")); + arissa->addWorldTranslation(Vector(0, 0, 100)); sceneView->getScene()->addPrimitiveComponent(arissa); core.renderLoop(); core.shutdown(); diff --git a/test/Engine/Containers/List.cpp b/test/Engine/Containers/List.cpp index 37f8c12..84dab80 100644 --- a/test/Engine/Containers/List.cpp +++ b/test/Engine/Containers/List.cpp @@ -10,9 +10,9 @@ BOOST_AUTO_TEST_CASE(basic_add) { List list; list.add(2); - BOOST_REQUIRE_EQUAL(list.length(), 1); + BOOST_REQUIRE_EQUAL(list.size(), 1); list.add(4); - BOOST_REQUIRE_EQUAL(list.length(), 2); + BOOST_REQUIRE_EQUAL(list.size(), 2); List::Iterator it = list.find(2); BOOST_REQUIRE_EQUAL(*it, 2); } @@ -26,7 +26,7 @@ BOOST_AUTO_TEST_CASE(basic_insert) List::Iterator it = list.find(3); it = list.insert(it, 1); BOOST_REQUIRE_EQUAL(*it, 1); - BOOST_REQUIRE_EQUAL(list.length(), 4); + BOOST_REQUIRE_EQUAL(list.size(), 4); } BOOST_AUTO_TEST_CASE(basic_remove) { @@ -37,7 +37,7 @@ BOOST_AUTO_TEST_CASE(basic_remove) List::Iterator it = list.find(3); it = list.remove(it); BOOST_REQUIRE_EQUAL(*it, 4); - BOOST_REQUIRE_EQUAL(list.length(), 2); + BOOST_REQUIRE_EQUAL(list.size(), 2); } BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file