Caching descriptor set updates
This commit is contained in:
Vendored
+1
-1
Submodule external/slang updated: 52b5bb43fd...539b91cb03
@@ -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]);
|
||||
|
||||
@@ -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,20 +86,23 @@ 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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -52,6 +52,10 @@ struct PointLight : ILightEnv
|
||||
}
|
||||
return result;
|
||||
}
|
||||
float3 getPosition()
|
||||
{
|
||||
return position_WS.xyz;
|
||||
}
|
||||
};
|
||||
|
||||
struct LightEnv
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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");
|
||||
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<Gfx::OComputeCommand> commands;
|
||||
@@ -120,6 +129,7 @@ void LightCullingPass::publishOutputs()
|
||||
|
||||
lightEnv = scene->getLightEnvironment();
|
||||
|
||||
{
|
||||
cullingLayout = graphics->createPipelineLayout("CullingLayout");
|
||||
cullingLayout->addDescriptorLayout(viewParamsLayout);
|
||||
cullingLayout->addDescriptorLayout(dispatchParamsLayout);
|
||||
@@ -139,6 +149,30 @@ void LightCullingPass::publishOutputs()
|
||||
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 = {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -185,6 +185,11 @@ DescriptorSet::~DescriptorSet()
|
||||
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) {
|
||||
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
|
||||
if (boundResources[binding] == vulkanBuffer->getAlloc())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bufferInfos.add(VkDescriptorBufferInfo{
|
||||
.buffer = vulkanBuffer->getHandle(),
|
||||
.offset = 0,
|
||||
@@ -207,6 +212,10 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBu
|
||||
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuffer) {
|
||||
PShaderBuffer vulkanBuffer = shaderBuffer.cast<ShaderBuffer>();
|
||||
if (boundResources[binding] == vulkanBuffer->getAlloc())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bufferInfos.add(VkDescriptorBufferInfo{
|
||||
.buffer = vulkanBuffer->getHandle(),
|
||||
@@ -229,6 +238,11 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuff
|
||||
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer shaderBuffer) {
|
||||
PShaderBuffer vulkanBuffer = shaderBuffer.cast<ShaderBuffer>();
|
||||
if (boundResources[binding] == vulkanBuffer->getAlloc())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bufferInfos.add(VkDescriptorBufferInfo{
|
||||
.buffer = vulkanBuffer->getHandle(),
|
||||
.offset = 0,
|
||||
@@ -251,6 +265,10 @@ void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuf
|
||||
|
||||
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState) {
|
||||
PSampler vulkanSampler = samplerState.cast<Sampler>();
|
||||
if (boundResources[binding] == vulkanSampler->getHandle())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
imageInfos.add(VkDescriptorImageInfo{
|
||||
.sampler = vulkanSampler->getSampler(),
|
||||
@@ -274,6 +292,10 @@ void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState)
|
||||
|
||||
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler samplerState) {
|
||||
TextureBase* vulkanTexture = texture.cast<TextureBase>().getHandle();
|
||||
if (boundResources[binding] == vulkanTexture->getHandle())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// It is assumed that the image is in the correct layout
|
||||
imageInfos.add(VkDescriptorImageInfo{
|
||||
@@ -284,7 +306,8 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
|
||||
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) {
|
||||
}
|
||||
else if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) {
|
||||
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||
}
|
||||
writeDescriptors.add(VkWriteDescriptorSet{
|
||||
@@ -306,6 +329,10 @@ void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture> te
|
||||
boundResources.resize(binding + textures.size());
|
||||
for (auto& gfxTexture : textures) {
|
||||
TextureBase* vulkanTexture = gfxTexture.cast<TextureBase>().getHandle();
|
||||
if (boundResources[binding + arrayElement] == vulkanTexture->getHandle())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
imageInfos.add(VkDescriptorImageInfo{
|
||||
.sampler = VK_NULL_HANDLE,
|
||||
.imageView = vulkanTexture->getView(),
|
||||
|
||||
@@ -17,7 +17,7 @@ Shader::Shader(PGraphics graphics, VkShaderStageFlags stage)
|
||||
|
||||
Shader::~Shader()
|
||||
{
|
||||
if(module != VK_NULL_HANDLE)
|
||||
if (module != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroyShaderModule(graphics->getDevice(), module, nullptr);
|
||||
}
|
||||
|
||||
@@ -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<uint64>::max(), imageAvailableSemaphores[currentSemaphoreIndex]->getHandle(), imageAvailableFences[currentSemaphoreIndex]->getHandle(), ¤tImageIndex);
|
||||
graphics->getGraphicsCommands()->getCommands()->waitForSemaphore(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, imageAvailableSemaphores[currentSemaphoreIndex]);
|
||||
|
||||
@@ -28,7 +28,7 @@ Slang::ComPtr<slang::IBlob> 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();
|
||||
|
||||
@@ -104,6 +104,16 @@ public:
|
||||
return object <=> rhs.object;
|
||||
}
|
||||
template<typename F>
|
||||
constexpr bool operator==(const RefPtr<F>& rhs) const noexcept
|
||||
{
|
||||
return object == rhs.getHandle();
|
||||
}
|
||||
template<typename F>
|
||||
constexpr auto operator<=>(const RefPtr<F>& rhs) const noexcept
|
||||
{
|
||||
return object <=> rhs.getHandle();
|
||||
}
|
||||
template<typename F>
|
||||
constexpr operator RefPtr<F>()
|
||||
{
|
||||
return RefPtr<F>(static_cast<F*>(object));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user