diff --git a/external/slang b/external/slang index 52b5bb4..539b91c 160000 --- a/external/slang +++ b/external/slang @@ -1 +1 @@ -Subproject commit 52b5bb43fd2933a30b405e7938ff62b209eea026 +Subproject commit 539b91cb03952dec78b21ded7d150ce3598aa412 diff --git a/res/shaders/ComputeFrustums.slang b/res/shaders/ComputeFrustums.slang index a1d5bbc..e6ad1f3 100644 --- a/res/shaders/ComputeFrustums.slang +++ b/res/shaders/ComputeFrustums.slang @@ -15,10 +15,10 @@ void computeFrustums(ComputeShaderInput in) { float3 origin = float3(0, 0, 0); float3 corners[4] = { - screenToView(float4(float2(in.dispatchThreadID.x + 0, in.dispatchThreadID.y + 0) * BLOCK_SIZE, -1.0f, 1.0f)).xyz, - screenToView(float4(float2(in.dispatchThreadID.x + 1, in.dispatchThreadID.y + 0) * BLOCK_SIZE, -1.0f, 1.0f)).xyz, - screenToView(float4(float2(in.dispatchThreadID.x + 0, in.dispatchThreadID.y + 1) * BLOCK_SIZE, -1.0f, 1.0f)).xyz, - screenToView(float4(float2(in.dispatchThreadID.x + 1, in.dispatchThreadID.y + 1) * BLOCK_SIZE, -1.0f, 1.0f)).xyz + screenToWorld(float4(float2(in.dispatchThreadID.x + 0, in.dispatchThreadID.y + 0) * BLOCK_SIZE, -1.0f, 1.0f)).xyz, + screenToWorld(float4(float2(in.dispatchThreadID.x + 1, in.dispatchThreadID.y + 0) * BLOCK_SIZE, -1.0f, 1.0f)).xyz, + screenToWorld(float4(float2(in.dispatchThreadID.x + 0, in.dispatchThreadID.y + 1) * BLOCK_SIZE, -1.0f, 1.0f)).xyz, + screenToWorld(float4(float2(in.dispatchThreadID.x + 1, in.dispatchThreadID.y + 1) * BLOCK_SIZE, -1.0f, 1.0f)).xyz }; Frustum frustum; frustum.sides[0] = computePlane(origin, corners[2], corners[0]); diff --git a/res/shaders/LightCulling.slang b/res/shaders/LightCulling.slang index a4b33dc..82d19eb 100644 --- a/res/shaders/LightCulling.slang +++ b/res/shaders/LightCulling.slang @@ -29,7 +29,6 @@ groupshared uint uMinDepth; groupshared uint uMaxDepth; groupshared Frustum groupFrustum; -groupshared float4x4 viewMatrix; groupshared uint oLightCount; groupshared uint oLightIndexStartOffset; @@ -70,7 +69,6 @@ void cullLights(ComputeShaderInput in) uint uDepth = asuint(fDepth); if(in.groupIndex == 0) { - viewMatrix = pViewParams.viewMatrix; uMinDepth = 0xffffffff; uMaxDepth = 0x0; oLightCount = 0; @@ -88,27 +86,30 @@ void cullLights(ComputeShaderInput in) float fMinDepth = asfloat(uMinDepth); float fMaxDepth = asfloat(uMaxDepth); - float minDepthVS = clipToView(float4(0, 0, fMinDepth, 1)).z; - float maxDepthVS = clipToView(float4(0, 0, fMaxDepth, 1)).z; - float nearClipVS = clipToView(float4(0, 0, 0, 1)).z; + float minDepthWS = clipToWorld(float4(0, 0, fMinDepth, 1)).z; + float maxDepthWS = clipToWorld(float4(0, 0, fMaxDepth, 1)).z; + float nearClipWS = clipToWorld(float4(0, 0, 0, 1)).z; - Plane minPlane = {float3(0, 0, -1), -minDepthVS}; + Plane minPlane = {float3(0, 0, -1), -minDepthWS}; for ( uint i = in.groupIndex; i < pLightEnv.numPointLights; i += BLOCK_SIZE * BLOCK_SIZE ) { PointLight light = pLightEnv.pointLights[i]; - float3 light_VS = mul(viewMatrix, float4(light.position_WS.xyz, 1.0f)).xyz; - //if(light.insideFrustum(groupFrustum, light_VS, nearClipVS, maxDepthVS)) +#ifdef LIGHT_CULLING + if(light.insideFrustum(groupFrustum, light.getPosition(), nearClipWS, maxDepthWS)) +#endif { tAppendLight(i); - //if(!light.insidePlane(minPlane, light_VS)) +#ifdef LIGHT_CULLING + if(!light.insidePlane(minPlane, light.getPosition())) +#endif { oAppendLight(i); } } } - GroupMemoryBarrierWithGroupSync(); + GroupMemoryBarrierWithGroupSync(); if(in.groupIndex == 0) { diff --git a/res/shaders/lib/Common.slang b/res/shaders/lib/Common.slang index 728434a..d928626 100644 --- a/res/shaders/lib/Common.slang +++ b/res/shaders/lib/Common.slang @@ -48,6 +48,13 @@ float4 clipToView(float4 clip) return view; } +float4 clipToWorld(float4 clip) +{ + float4 view = clipToView(clip); + + return viewToWorld(view); +} + float4 screenToView(float4 screen) { float2 texCoord = screen.xy / pViewParams.screenDimensions; diff --git a/res/shaders/lib/LightEnv.slang b/res/shaders/lib/LightEnv.slang index 75813c5..ca6732a 100644 --- a/res/shaders/lib/LightEnv.slang +++ b/res/shaders/lib/LightEnv.slang @@ -52,6 +52,10 @@ struct PointLight : ILightEnv } return result; } + float3 getPosition() + { + return position_WS.xyz; + } }; struct LightEnv diff --git a/src/Editor/Asset/MeshLoader.cpp b/src/Editor/Asset/MeshLoader.cpp index e440e6a..3e5191e 100644 --- a/src/Editor/Asset/MeshLoader.cpp +++ b/src/Editor/Asset/MeshLoader.cpp @@ -38,7 +38,7 @@ void MeshLoader::importAsset(MeshImportArgs args) PMeshAsset ref = asset; asset->setStatus(Asset::Status::Loading); AssetRegistry::get().registerMesh(std::move(asset)); -import(args, ref); + import(args, ref); } diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index 8375a80..a50bfb7 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -58,6 +58,10 @@ int main() { AssetImporter::importMesh(MeshImportArgs{ .filePath = sourcePath / "import/models/cube.fbx", }); + //AssetImporter::importMesh(MeshImportArgs{ + // .filePath = sourcePath / "import/models/greek-temple/source/greek-temple.fbx", + // .importPath = "temple" + // }); AssetImporter::importMesh(MeshImportArgs{ .filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.fbx", .importPath = "Whitechapel" diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index 1a38f06..0a8886c 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -8,6 +8,8 @@ using namespace Seele; +extern bool useLightCulling; + LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) { @@ -63,7 +65,14 @@ void LightCullingPass::render() cullingDescriptorSet->updateTexture(6, Gfx::PTexture2D(tLightGrid)); cullingDescriptorSet->writeChanges(); Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand"); - computeCommand->bindPipeline(cullingPipeline); + if (useLightCulling) + { + computeCommand->bindPipeline(cullingEnabledPipeline); + } + else + { + computeCommand->bindPipeline(cullingPipeline); + } computeCommand->bindDescriptor({ viewParamsSet, dispatchParamsSet, cullingDescriptorSet, lightEnv->getDescriptorSet() }); computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z); Array commands; @@ -120,26 +129,51 @@ void LightCullingPass::publishOutputs() lightEnv = scene->getLightEnvironment(); - cullingLayout = graphics->createPipelineLayout("CullingLayout"); - cullingLayout->addDescriptorLayout(viewParamsLayout); - cullingLayout->addDescriptorLayout(dispatchParamsLayout); - cullingLayout->addDescriptorLayout(cullingDescriptorLayout); - cullingLayout->addDescriptorLayout(lightEnv->getDescriptorLayout()); + { + cullingLayout = graphics->createPipelineLayout("CullingLayout"); + cullingLayout->addDescriptorLayout(viewParamsLayout); + cullingLayout->addDescriptorLayout(dispatchParamsLayout); + cullingLayout->addDescriptorLayout(cullingDescriptorLayout); + cullingLayout->addDescriptorLayout(lightEnv->getDescriptorLayout()); - ShaderCreateInfo createInfo = { - .name = "Culling", - .mainModule = "LightCulling", - .entryPoint = "cullLights", - .rootSignature = cullingLayout, - }; - cullingShader = graphics->createComputeShader(createInfo); - cullingLayout->create(); + ShaderCreateInfo createInfo = { + .name = "Culling", + .mainModule = "LightCulling", + .entryPoint = "cullLights", + .rootSignature = cullingLayout, + }; + cullingShader = graphics->createComputeShader(createInfo); + cullingLayout->create(); - Gfx::ComputePipelineCreateInfo pipelineInfo; - pipelineInfo.computeShader = cullingShader; - pipelineInfo.pipelineLayout = std::move(cullingLayout); - cullingPipeline = graphics->createComputePipeline(std::move(pipelineInfo)); + Gfx::ComputePipelineCreateInfo pipelineInfo; + pipelineInfo.computeShader = cullingShader; + pipelineInfo.pipelineLayout = std::move(cullingLayout); + cullingPipeline = graphics->createComputePipeline(std::move(pipelineInfo)); + } + { + cullingEnableLayout = graphics->createPipelineLayout("CullingEnabledLayout"); + cullingEnableLayout->addDescriptorLayout(viewParamsLayout); + cullingEnableLayout->addDescriptorLayout(dispatchParamsLayout); + cullingEnableLayout->addDescriptorLayout(cullingDescriptorLayout); + cullingEnableLayout->addDescriptorLayout(lightEnv->getDescriptorLayout()); + + ShaderCreateInfo createInfo = { + .name = "Culling", + .mainModule = "LightCulling", + .entryPoint = "cullLights", + .rootSignature = cullingEnableLayout, + }; + createInfo.defines["LIGHT_CULLING"] = "1"; + cullingEnabledShader = graphics->createComputeShader(createInfo); + cullingEnableLayout->create(); + + Gfx::ComputePipelineCreateInfo pipelineInfo; + pipelineInfo.computeShader = cullingShader; + pipelineInfo.pipelineLayout = std::move(cullingEnableLayout); + cullingEnabledPipeline = graphics->createComputePipeline(std::move(pipelineInfo)); + } + uint32 counterReset = 0; ShaderBufferCreateInfo structInfo = { .sourceData = { diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.h b/src/Engine/Graphics/RenderPass/LightCullingPass.h index 5fe6a2e..87f64c8 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.h +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.h @@ -60,9 +60,12 @@ private: Gfx::OTexture2D tLightGrid; Gfx::PDescriptorSet cullingDescriptorSet; Gfx::ODescriptorLayout cullingDescriptorLayout; - Gfx::OComputeShader cullingShader; - Gfx::PComputePipeline cullingPipeline; Gfx::OPipelineLayout cullingLayout; + Gfx::OPipelineLayout cullingEnableLayout; + Gfx::OComputeShader cullingShader; + Gfx::OComputeShader cullingEnabledShader; + Gfx::PComputePipeline cullingPipeline; + Gfx::PComputePipeline cullingEnabledPipeline; }; DEFINE_REF(LightCullingPass) } // namespace Seele diff --git a/src/Engine/Graphics/Vulkan/Descriptor.cpp b/src/Engine/Graphics/Vulkan/Descriptor.cpp index 12c7899..7776452 100644 --- a/src/Engine/Graphics/Vulkan/Descriptor.cpp +++ b/src/Engine/Graphics/Vulkan/Descriptor.cpp @@ -12,81 +12,81 @@ DescriptorLayout::DescriptorLayout(PGraphics graphics, const std::string& name) DescriptorLayout::~DescriptorLayout() { graphics->getDestructionManager()->queueResourceForDestruction(std::move(pool)); - 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()); - Array bindingFlags(descriptorBindings.size()); - for (size_t i = 0; i < descriptorBindings.size(); ++i) { - const Gfx::DescriptorBinding& gfxBinding = descriptorBindings[i]; - bindings[i] = { - .binding = gfxBinding.binding, - .descriptorType = cast(gfxBinding.descriptorType), - .descriptorCount = gfxBinding.descriptorCount, - .stageFlags = gfxBinding.shaderStages, - .pImmutableSamplers = nullptr, + if (layoutHandle != VK_NULL_HANDLE) { + return; + } + bindings.resize(descriptorBindings.size()); + Array bindingFlags(descriptorBindings.size()); + for (size_t i = 0; i < descriptorBindings.size(); ++i) { + const Gfx::DescriptorBinding& gfxBinding = descriptorBindings[i]; + bindings[i] = { + .binding = gfxBinding.binding, + .descriptorType = cast(gfxBinding.descriptorType), + .descriptorCount = gfxBinding.descriptorCount, + .stageFlags = gfxBinding.shaderStages, + .pImmutableSamplers = nullptr, + }; + bindingFlags[i] = gfxBinding.bindingFlags; + } + VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, + .pNext = nullptr, + .bindingCount = static_cast(bindingFlags.size()), + .pBindingFlags = bindingFlags.data(), }; - bindingFlags[i] = gfxBinding.bindingFlags; - } - VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, - .pNext = nullptr, - .bindingCount = static_cast(bindingFlags.size()), - .pBindingFlags = bindingFlags.data(), - }; - VkDescriptorSetLayoutCreateInfo createInfo = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .pNext = &bindingFlagsInfo, - .flags = 0, - .bindingCount = (uint32)bindings.size(), - .pBindings = bindings.data(), - }; - VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle)); + VkDescriptorSetLayoutCreateInfo createInfo = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .pNext = &bindingFlagsInfo, + .flags = 0, + .bindingCount = (uint32)bindings.size(), + .pBindings = bindings.data(), + }; + VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle)); - pool = new DescriptorPool(graphics, this); + pool = new DescriptorPool(graphics, this); - hash = CRC::Calculate(bindings.data(), sizeof(VkDescriptorSetLayoutBinding) * bindings.size(), CRC::CRC_32()); + hash = CRC::Calculate(bindings.data(), sizeof(VkDescriptorSetLayoutBinding) * bindings.size(), CRC::CRC_32()); } -DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout) +DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout) : CommandBoundResource(graphics) , graphics(graphics) , layout(layout) { - 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); + for (uint32 i = 0; i < cachedHandles.size(); ++i) { + cachedHandles[i] = nullptr; } - } - VkDescriptorPoolCreateInfo createInfo = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .maxSets = maxSets * Gfx::numFramesBuffered, - .poolSizeCount = (uint32)poolSizes.size(), - .pPoolSizes = poolSizes.data(), - }; - 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 = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .maxSets = maxSets * Gfx::numFramesBuffered, + .poolSizeCount = (uint32)poolSizes.size(), + .pPoolSizes = poolSizes.data(), + }; + VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle)); } DescriptorPool::~DescriptorPool() { @@ -104,66 +104,66 @@ DescriptorPool::~DescriptorPool() { } Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet() { - VkDescriptorSetLayout layoutHandle = layout->getHandle(); - VkDescriptorSetVariableDescriptorCountAllocateInfo setCounts = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO, - .pNext = nullptr, - .descriptorSetCount = 1, - }; - VkDescriptorSetAllocateInfo allocInfo = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .pNext = nullptr, - .descriptorPool = poolHandle, - .descriptorSetCount = 1, - .pSetLayouts = &layoutHandle, - }; - uint32 counts = 0; - for (const auto& binding : layout->bindings) { - if (binding.descriptorCount > 0) { - counts = binding.descriptorCount; + VkDescriptorSetLayout layoutHandle = layout->getHandle(); + VkDescriptorSetVariableDescriptorCountAllocateInfo setCounts = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO, + .pNext = nullptr, + .descriptorSetCount = 1, + }; + VkDescriptorSetAllocateInfo allocInfo = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .pNext = nullptr, + .descriptorPool = poolHandle, + .descriptorSetCount = 1, + .pSetLayouts = &layoutHandle, + }; + uint32 counts = 0; + for (const auto& binding : layout->bindings) { + if (binding.descriptorCount > 0) { + counts = binding.descriptorCount; + } } - } - if (layout->bindings.size() > 0) { - setCounts.pDescriptorCounts = &counts; - allocInfo.pNext = &setCounts; - } - for (uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex) { - if (cachedHandles[setIndex] == nullptr) { - cachedHandles[setIndex] = new DescriptorSet(graphics, this); + if (layout->bindings.size() > 0) { + setCounts.pDescriptorCounts = &counts; + allocInfo.pNext = &setCounts; } - 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(); + 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(); - PDescriptorSet vulkanSet = cachedHandles[setIndex]; + PDescriptorSet vulkanSet = cachedHandles[setIndex]; - // Found set, stop searching - return vulkanSet; - } - if (nextAlloc == nullptr) { - nextAlloc = new DescriptorPool(graphics, layout); - } - // std::cout << "Out of descriptors, forwarding" << std::endl; - return nextAlloc->allocateDescriptorSet(); - // throw std::logic_error("Out of descriptor sets"); + // Found set, stop searching + return vulkanSet; + } + if (nextAlloc == nullptr) { + nextAlloc = new DescriptorPool(graphics, layout); + } + // std::cout << "Out of descriptors, forwarding" << std::endl; + return nextAlloc->allocateDescriptorSet(); + // throw std::logic_error("Out of descriptor sets"); } void DescriptorPool::reset() { - for (uint32 i = 0; i < cachedHandles.size(); ++i) { - if (cachedHandles[i] == nullptr) { - return; + for (uint32 i = 0; i < cachedHandles.size(); ++i) { + if (cachedHandles[i] == nullptr) { + return; + } + cachedHandles[i]->free(); + } + if (nextAlloc != nullptr) { + nextAlloc->reset(); } - cachedHandles[i]->free(); - } - if (nextAlloc != nullptr) { - nextAlloc->reset(); - } } DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner) @@ -184,51 +184,65 @@ DescriptorSet::~DescriptorSet() } void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) { - PUniformBuffer vulkanBuffer = uniformBuffer.cast(); - bufferInfos.add(VkDescriptorBufferInfo{ - .buffer = vulkanBuffer->getHandle(), - .offset = 0, - .range = vulkanBuffer->getSize(), - }); + PUniformBuffer vulkanBuffer = uniformBuffer.cast(); + if (boundResources[binding] == vulkanBuffer->getAlloc()) + { + return; + } - writeDescriptors.add(VkWriteDescriptorSet{ - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = setHandle, - .dstBinding = binding, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = cast(layout->getBindings()[binding].descriptorType), - .pBufferInfo = &bufferInfos.back(), - }); + bufferInfos.add(VkDescriptorBufferInfo{ + .buffer = vulkanBuffer->getHandle(), + .offset = 0, + .range = vulkanBuffer->getSize(), + }); - boundResources[binding] = vulkanBuffer->getAlloc(); + writeDescriptors.add(VkWriteDescriptorSet{ + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = setHandle, + .dstBinding = binding, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = cast(layout->getBindings()[binding].descriptorType), + .pBufferInfo = &bufferInfos.back(), + }); + + boundResources[binding] = vulkanBuffer->getAlloc(); } void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuffer) { - PShaderBuffer vulkanBuffer = shaderBuffer.cast(); + PShaderBuffer vulkanBuffer = shaderBuffer.cast(); + if (boundResources[binding] == vulkanBuffer->getAlloc()) + { + return; + } - bufferInfos.add(VkDescriptorBufferInfo{ - .buffer = vulkanBuffer->getHandle(), - .offset = 0, - .range = vulkanBuffer->getSize(), - }); - writeDescriptors.add(VkWriteDescriptorSet{ - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = setHandle, - .dstBinding = binding, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = cast(layout->getBindings()[binding].descriptorType), - .pBufferInfo = &bufferInfos.back(), - }); + bufferInfos.add(VkDescriptorBufferInfo{ + .buffer = vulkanBuffer->getHandle(), + .offset = 0, + .range = vulkanBuffer->getSize(), + }); + writeDescriptors.add(VkWriteDescriptorSet{ + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = setHandle, + .dstBinding = binding, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = cast(layout->getBindings()[binding].descriptorType), + .pBufferInfo = &bufferInfos.back(), + }); - boundResources[binding] = vulkanBuffer->getAlloc(); + boundResources[binding] = vulkanBuffer->getAlloc(); } void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer shaderBuffer) { PShaderBuffer vulkanBuffer = shaderBuffer.cast(); + if (boundResources[binding] == vulkanBuffer->getAlloc()) + { + return; + } + bufferInfos.add(VkDescriptorBufferInfo{ .buffer = vulkanBuffer->getHandle(), .offset = 0, @@ -250,98 +264,111 @@ void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuf } void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState) { - PSampler vulkanSampler = samplerState.cast(); - - imageInfos.add(VkDescriptorImageInfo{ - .sampler = vulkanSampler->getSampler(), - .imageView = VK_NULL_HANDLE, - .imageLayout = VK_IMAGE_LAYOUT_UNDEFINED, - }); - - writeDescriptors.add(VkWriteDescriptorSet{ - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = setHandle, - .dstBinding = binding, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, - .pImageInfo = &imageInfos.back(), - }); - - boundResources[binding] = vulkanSampler->getHandle(); -} - -void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler samplerState) { - TextureBase* vulkanTexture = texture.cast().getHandle(); - - // It is assumed that the image is in the correct layout - imageInfos.add(VkDescriptorImageInfo{ - .sampler = samplerState != nullptr ? samplerState.cast()->getSampler() : VK_NULL_HANDLE, - .imageView = vulkanTexture->getView(), - .imageLayout = cast(vulkanTexture->getLayout()), - }); - VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; - if (samplerState != nullptr) { - descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - } else if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) { - descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - } - writeDescriptors.add(VkWriteDescriptorSet{ - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = setHandle, - .dstBinding = binding, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = descriptorType, - .pImageInfo = &imageInfos.back(), - }); - - boundResources[binding] = vulkanTexture->getHandle(); -} -void DescriptorSet::updateTextureArray(uint32_t binding, Array textures) { - // maybe make this a parameter? - uint32 arrayElement = 0; - boundResources.resize(binding + textures.size()); - for (auto& gfxTexture : textures) { - TextureBase* vulkanTexture = gfxTexture.cast().getHandle(); - imageInfos.add(VkDescriptorImageInfo{ - .sampler = VK_NULL_HANDLE, - .imageView = vulkanTexture->getView(), - .imageLayout = cast(vulkanTexture->getLayout()), - }); - - VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; - if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) { - descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + PSampler vulkanSampler = samplerState.cast(); + if (boundResources[binding] == vulkanSampler->getHandle()) + { + return; } - boundResources[binding + arrayElement] = vulkanTexture->getHandle(); + + imageInfos.add(VkDescriptorImageInfo{ + .sampler = vulkanSampler->getSampler(), + .imageView = VK_NULL_HANDLE, + .imageLayout = VK_IMAGE_LAYOUT_UNDEFINED, + }); + writeDescriptors.add(VkWriteDescriptorSet{ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, .pNext = nullptr, .dstSet = setHandle, .dstBinding = binding, - .dstArrayElement = arrayElement++, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, + .pImageInfo = &imageInfos.back(), + }); + + boundResources[binding] = vulkanSampler->getHandle(); +} + +void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler samplerState) { + TextureBase* vulkanTexture = texture.cast().getHandle(); + if (boundResources[binding] == vulkanTexture->getHandle()) + { + return; + } + + // It is assumed that the image is in the correct layout + imageInfos.add(VkDescriptorImageInfo{ + .sampler = samplerState != nullptr ? samplerState.cast()->getSampler() : VK_NULL_HANDLE, + .imageView = vulkanTexture->getView(), + .imageLayout = cast(vulkanTexture->getLayout()), + }); + VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + if (samplerState != nullptr) { + descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + } + else if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) { + descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + } + writeDescriptors.add(VkWriteDescriptorSet{ + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = setHandle, + .dstBinding = binding, + .dstArrayElement = 0, .descriptorCount = 1, .descriptorType = descriptorType, .pImageInfo = &imageInfos.back(), - }); - vulkanTexture->getHandle()->bind(); - } + }); + + boundResources[binding] = vulkanTexture->getHandle(); +} +void DescriptorSet::updateTextureArray(uint32_t binding, Array textures) { + // maybe make this a parameter? + uint32 arrayElement = 0; + boundResources.resize(binding + textures.size()); + for (auto& gfxTexture : textures) { + TextureBase* vulkanTexture = gfxTexture.cast().getHandle(); + if (boundResources[binding + arrayElement] == vulkanTexture->getHandle()) + { + continue; + } + imageInfos.add(VkDescriptorImageInfo{ + .sampler = VK_NULL_HANDLE, + .imageView = vulkanTexture->getView(), + .imageLayout = cast(vulkanTexture->getLayout()), + }); + + VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) { + descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + } + boundResources[binding + arrayElement] = vulkanTexture->getHandle(); + writeDescriptors.add(VkWriteDescriptorSet{ + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = setHandle, + .dstBinding = binding, + .dstArrayElement = arrayElement++, + .descriptorCount = 1, + .descriptorType = descriptorType, + .pImageInfo = &imageInfos.back(), + }); + vulkanTexture->getHandle()->bind(); + } } void DescriptorSet::writeChanges() { - if (writeDescriptors.size() > 0) { - if (isCurrentlyBound()) { - std::cout << "Descriptor currently bound, allocate a new one instead" << std::endl; - assert(!isCurrentlyBound()); + 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(); } - vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr); - writeDescriptors.clear(); - imageInfos.clear(); - bufferInfos.clear(); - } } PipelineLayout::PipelineLayout(PGraphics graphics, const std::string& name, Gfx::PPipelineLayout baseLayout) @@ -353,46 +380,46 @@ std::mutex layoutLock; Map cachedLayouts; void PipelineLayout::create() { - for (auto [name, desc] : descriptorSetLayouts) { - PDescriptorLayout layout = desc.cast(); - layout->create(); - uint32 parameterIndex = parameterMapping[layout->getName()]; - if (parameterIndex >= vulkanDescriptorLayouts.size()) - { - vulkanDescriptorLayouts.resize(parameterIndex + 1); + for (auto [name, desc] : descriptorSetLayouts) { + PDescriptorLayout layout = desc.cast(); + layout->create(); + uint32 parameterIndex = parameterMapping[layout->getName()]; + if (parameterIndex >= vulkanDescriptorLayouts.size()) + { + vulkanDescriptorLayouts.resize(parameterIndex + 1); + } + vulkanDescriptorLayouts[parameterIndex] = layout->getHandle(); } - vulkanDescriptorLayouts[parameterIndex] = layout->getHandle(); - } - 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 = pushConstants[i].stageFlags; - } + 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 = pushConstants[i].stageFlags; + } - VkPipelineLayoutCreateInfo createInfo = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .setLayoutCount = (uint32)vulkanDescriptorLayouts.size(), - .pSetLayouts = vulkanDescriptorLayouts.data(), - .pushConstantRangeCount = (uint32)vkPushConstants.size(), - .pPushConstantRanges = vkPushConstants.data(), - }; + VkPipelineLayoutCreateInfo createInfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .setLayoutCount = (uint32)vulkanDescriptorLayouts.size(), + .pSetLayouts = vulkanDescriptorLayouts.data(), + .pushConstantRangeCount = (uint32)vkPushConstants.size(), + .pPushConstantRanges = vkPushConstants.data(), + }; - layoutHash = CRC::Calculate(createInfo.pPushConstantRanges, - sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount, CRC::CRC_32()); - layoutHash = CRC::Calculate(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount, - CRC::CRC_32(), layoutHash); + layoutHash = CRC::Calculate(createInfo.pPushConstantRanges, + sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount, CRC::CRC_32()); + layoutHash = CRC::Calculate(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount, + CRC::CRC_32(), layoutHash); - std::unique_lock l(layoutLock); - if (cachedLayouts.contains(layoutHash)) { - // std::cout << "New Layout" << std::endl; - layoutHandle = cachedLayouts[layoutHash]; - return; - } + std::unique_lock l(layoutLock); + if (cachedLayouts.contains(layoutHash)) { + // std::cout << "New Layout" << std::endl; + layoutHandle = cachedLayouts[layoutHash]; + return; + } - VK_CHECK(vkCreatePipelineLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle)); - cachedLayouts[layoutHash] = layoutHandle; + VK_CHECK(vkCreatePipelineLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle)); + cachedLayouts[layoutHash] = layoutHandle; } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/Shader.cpp b/src/Engine/Graphics/Vulkan/Shader.cpp index 755b2b8..35156de 100644 --- a/src/Engine/Graphics/Vulkan/Shader.cpp +++ b/src/Engine/Graphics/Vulkan/Shader.cpp @@ -9,15 +9,15 @@ using namespace Seele; using namespace Seele::Vulkan; -Shader::Shader(PGraphics graphics, VkShaderStageFlags stage) +Shader::Shader(PGraphics graphics, VkShaderStageFlags stage) : graphics(graphics) , stage(stage) { } -Shader::~Shader() +Shader::~Shader() { - if(module != VK_NULL_HANDLE) + if (module != VK_NULL_HANDLE) { vkDestroyShaderModule(graphics->getDevice(), module, nullptr); } @@ -30,9 +30,9 @@ uint32 Seele::Vulkan::Shader::getShaderHash() const void Shader::create(ShaderCreateInfo createInfo) { - Map paramMapping; - Slang::ComPtr kernelBlob = generateShader(createInfo, SLANG_SPIRV, paramMapping); - createInfo.rootSignature->addMapping(paramMapping); + Map paramMapping; + Slang::ComPtr kernelBlob = generateShader(createInfo, SLANG_SPIRV, paramMapping); + createInfo.rootSignature->addMapping(paramMapping); VkShaderModuleCreateInfo moduleInfo = { .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, diff --git a/src/Engine/Graphics/Vulkan/Window.cpp b/src/Engine/Graphics/Vulkan/Window.cpp index cf91f1f..9481ae8 100644 --- a/src/Engine/Graphics/Vulkan/Window.cpp +++ b/src/Engine/Graphics/Vulkan/Window.cpp @@ -114,7 +114,7 @@ void Window::pollInput() void Window::beginFrame() { - imageAvailableFences[currentSemaphoreIndex]->wait(100000000); + imageAvailableFences[currentSemaphoreIndex]->wait(10000000000); imageAvailableFences[currentSemaphoreIndex]->reset(); vkAcquireNextImageKHR(graphics->getDevice(), swapchain, std::numeric_limits::max(), imageAvailableSemaphores[currentSemaphoreIndex]->getHandle(), imageAvailableFences[currentSemaphoreIndex]->getHandle(), ¤tImageIndex); graphics->getGraphicsCommands()->getCommands()->waitForSemaphore(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, imageAvailableSemaphores[currentSemaphoreIndex]); diff --git a/src/Engine/Graphics/slang-compile.cpp b/src/Engine/Graphics/slang-compile.cpp index 0501fbd..fe1e386 100644 --- a/src/Engine/Graphics/slang-compile.cpp +++ b/src/Engine/Graphics/slang-compile.cpp @@ -28,7 +28,7 @@ Slang::ComPtr Seele::generateShader(const ShaderCreateInfo& create option[2].value.intValue0 = SLANG_DEBUG_INFO_LEVEL_NONE; option[3].name = slang::CompilerOptionName::DebugInformationFormat; option[3].value.kind = slang::CompilerOptionValueKind::Int; - option[3].value.intValue0 = SLANG_DEBUG_INFO_FORMAT_PDB; + option[3].value.intValue0 = SLANG_DEBUG_INFO_FORMAT_DEFAULT; sessionDesc.compilerOptionEntries = option.data(); sessionDesc.compilerOptionEntryCount = option.size(); diff --git a/src/Engine/MinimalEngine.h b/src/Engine/MinimalEngine.h index 2aff069..cc2316b 100644 --- a/src/Engine/MinimalEngine.h +++ b/src/Engine/MinimalEngine.h @@ -104,6 +104,16 @@ public: return object <=> rhs.object; } template + constexpr bool operator==(const RefPtr& rhs) const noexcept + { + return object == rhs.getHandle(); + } + template + constexpr auto operator<=>(const RefPtr& rhs) const noexcept + { + return object <=> rhs.getHandle(); + } + template constexpr operator RefPtr() { return RefPtr(static_cast(object)); diff --git a/src/Engine/Window/GameView.cpp b/src/Engine/Window/GameView.cpp index f389261..dd03ae4 100644 --- a/src/Engine/Window/GameView.cpp +++ b/src/Engine/Window/GameView.cpp @@ -14,6 +14,7 @@ using namespace Seele; bool usePositionOnly = false; bool useViewCulling = false; +bool useLightCulling = false; GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo, std::string dllPath) : View(graphics, window, createInfo, "Game") @@ -103,19 +104,18 @@ void GameView::keyCallback(KeyCode code, InputAction action, KeyModifier modifie keyboardSystem->keyCallback(code, action, modifier); if (code == KeyCode::KEY_P && action == InputAction::RELEASE) { - usePositionOnly = true; + usePositionOnly = !usePositionOnly; + std::cout << "Use Pos only " << usePositionOnly << std::endl; } if (code == KeyCode::KEY_O && action == InputAction::RELEASE) { - usePositionOnly = false; + useViewCulling = !useViewCulling; + std::cout << "Use View Culling " << useViewCulling << std::endl; } if (code == KeyCode::KEY_L && action == InputAction::RELEASE) { - useViewCulling = true; - } - if (code == KeyCode::KEY_K && action == InputAction::RELEASE) - { - useViewCulling = false; + useLightCulling = !useLightCulling; + std::cout << "Use Light Culling " << useLightCulling << std::endl; } }