Skip to content

Commit

Permalink
[vulkan] fixed validation errors related to bindless samplers being d…
Browse files Browse the repository at this point in the history
…estroyed when changing resolution (to match mip bias for a given resolution)
  • Loading branch information
PanosK92 committed Feb 6, 2025
1 parent aafe880 commit 5213be8
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 41 deletions.
1 change: 0 additions & 1 deletion runtime/RHI/RHI_Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ namespace spartan
static void* GetQueueRhiResource(const RHI_Queue_Type type);

// descriptors
static void CreateDescriptorPool();
static void AllocateDescriptorSet(void*& resource, RHI_DescriptorSetLayout* descriptor_set_layout, const std::vector<RHI_Descriptor>& descriptors);
static std::unordered_map<uint64_t, RHI_DescriptorSet>& GetDescriptorSets();
static void* GetDescriptorSet(const RHI_Device_Bindless_Resource resource_type);
Expand Down
62 changes: 32 additions & 30 deletions runtime/RHI/Vulkan/Vulkan_Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,32 @@ namespace spartan
unordered_map<uint64_t, shared_ptr<RHI_Pipeline>> pipelines;
unordered_map<uint64_t, vector<RHI_Descriptor>> descriptor_cache;

void create_pool()
{
static array<VkDescriptorPoolSize, 5> pool_sizes =
{
VkDescriptorPoolSize{ VK_DESCRIPTOR_TYPE_SAMPLER, rhi_max_array_size * rhi_max_descriptor_set_count },
VkDescriptorPoolSize{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, rhi_max_array_size * rhi_max_descriptor_set_count },
VkDescriptorPoolSize{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, rhi_max_array_size * rhi_max_descriptor_set_count },
VkDescriptorPoolSize{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, rhi_max_array_size * rhi_max_descriptor_set_count },
VkDescriptorPoolSize{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rhi_max_array_size * rhi_max_descriptor_set_count }
};

// describe
VkDescriptorPoolCreateInfo pool_create_info = {};
pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT;
pool_create_info.poolSizeCount = static_cast<uint32_t>(pool_sizes.size());
pool_create_info.pPoolSizes = pool_sizes.data();
pool_create_info.maxSets = rhi_max_descriptor_set_count;

// create
SP_ASSERT(descriptors::descriptor_pool == nullptr);
SP_ASSERT_VK(vkCreateDescriptorPool(RHI_Context::device, &pool_create_info, nullptr, &descriptors::descriptor_pool));

Profiler::m_descriptor_set_count = 0;
}

void merge_descriptors(vector<RHI_Descriptor>& base_descriptors, const std::vector<RHI_Descriptor>& additional_descriptors)
{
for (const RHI_Descriptor& descriptor_additional : additional_descriptors)
Expand Down Expand Up @@ -1445,7 +1471,7 @@ namespace spartan
}

vulkan_memory_allocator::initialize();
CreateDescriptorPool();
descriptors::create_pool();

// gpu dependent actions
{
Expand Down Expand Up @@ -1579,7 +1605,7 @@ namespace spartan
void RHI_Device::DeletionQueueParse()
{
lock_guard<mutex> guard(mutex_deletion_queue);

for (auto& it : deletion_queue)
{
RHI_Resource_Type resource_type = it.first;
Expand All @@ -1605,7 +1631,7 @@ namespace spartan
}

// delete descriptor sets which are now invalid (because they are referring to a deleted resource)
if (resource_type == RHI_Resource_Type::TextureView || resource_type == RHI_Resource_Type::Buffer || resource_type == RHI_Resource_Type::Sampler)
if (resource_type == RHI_Resource_Type::TextureView || resource_type == RHI_Resource_Type::Buffer)
{
for (auto it = descriptors::sets.begin(); it != descriptors::sets.end();)
{
Expand All @@ -1621,6 +1647,8 @@ namespace spartan
}
}
}

// samplers are bindless so they just update the set again
}
}

Expand Down Expand Up @@ -1666,32 +1694,6 @@ namespace spartan

// descriptors

void RHI_Device::CreateDescriptorPool()
{
static array<VkDescriptorPoolSize, 5> pool_sizes =
{
VkDescriptorPoolSize{ VK_DESCRIPTOR_TYPE_SAMPLER, rhi_max_array_size * rhi_max_descriptor_set_count },
VkDescriptorPoolSize{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, rhi_max_array_size * rhi_max_descriptor_set_count },
VkDescriptorPoolSize{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, rhi_max_array_size * rhi_max_descriptor_set_count },
VkDescriptorPoolSize{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, rhi_max_array_size * rhi_max_descriptor_set_count },
VkDescriptorPoolSize{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rhi_max_array_size * rhi_max_descriptor_set_count }
};

// describe
VkDescriptorPoolCreateInfo pool_create_info = {};
pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT;
pool_create_info.poolSizeCount = static_cast<uint32_t>(pool_sizes.size());
pool_create_info.pPoolSizes = pool_sizes.data();
pool_create_info.maxSets = rhi_max_descriptor_set_count;

// create
SP_ASSERT(descriptors::descriptor_pool == nullptr);
SP_ASSERT_VK(vkCreateDescriptorPool(RHI_Context::device, &pool_create_info, nullptr, &descriptors::descriptor_pool));

Profiler::m_descriptor_set_count = 0;
}

void RHI_Device::AllocateDescriptorSet(void*& resource, RHI_DescriptorSetLayout* descriptor_set_layout, const vector<RHI_Descriptor>& descriptors_)
{
// describe
Expand Down Expand Up @@ -1748,7 +1750,7 @@ namespace spartan
array<RHI_Texture*, rhi_max_array_size>* material_textures,
RHI_Buffer* material_parameters,
RHI_Buffer* light_parameters,
const std::array<std::shared_ptr<RHI_Sampler>, static_cast<uint32_t>(Renderer_Sampler::Max)>* samplers
const array<shared_ptr<RHI_Sampler>, static_cast<uint32_t>(Renderer_Sampler::Max)>* samplers
)
{
if (samplers)
Expand Down
4 changes: 2 additions & 2 deletions runtime/RHI/Vulkan/Vulkan_FidelityFX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,6 @@ namespace spartan
{
if (context_created)
{
RHI_Device::QueueWaitAll();

SP_ASSERT(ffxFsr3UpscalerContextDestroy(&context) == FFX_OK);
context_created = false;

Expand Down Expand Up @@ -994,6 +992,8 @@ namespace spartan
void RHI_FidelityFX::Resize(const Vector2& resolution_render, const Vector2& resolution_output)
{
#ifdef _WIN32
RHI_Device::QueueWaitAll();

bool resolution_render_changed = resolution_render.x != resolution_render_width || resolution_render.y != resolution_render_height;
bool resolution_output_changed = resolution_output.x != resolution_output_width || resolution_output.y != resolution_output_height;

Expand Down
13 changes: 13 additions & 0 deletions runtime/Rendering/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ namespace spartan
array<Sb_Light, rhi_max_array_size_lights> binldess_lights;
bool bindless_materials_dirty = true;
bool bindless_lights_dirty = true;
bool bindless_samplers_dirty = true;

// misc
unordered_map<Renderer_Option, float> m_options;
Expand Down Expand Up @@ -627,6 +628,13 @@ namespace spartan
}
}

if (bindless_samplers_dirty)
{
RHI_Device::UpdateBindlessResources(nullptr, nullptr, nullptr, &Renderer::GetSamplers());

bindless_samplers_dirty = false;
}

if (bindless_materials_dirty)
{
// update parameters buffer
Expand Down Expand Up @@ -1080,6 +1088,11 @@ namespace spartan
buffer->Update(cmd_list, &binldess_lights[0], update_size);
}

void Renderer::BindlessUpdateSamplers()
{
bindless_samplers_dirty = true;
}

void Renderer::Screenshot(const string& file_path)
{
GetRenderTarget(Renderer_RenderTarget::frame_output)->SaveAsImage(file_path);
Expand Down
3 changes: 2 additions & 1 deletion runtime/Rendering/Renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,14 @@ namespace spartan
static std::array<std::shared_ptr<RHI_Texture>, static_cast<uint32_t>(Renderer_RenderTarget::max)>& GetRenderTargets();
static std::array<std::shared_ptr<RHI_Shader>, static_cast<uint32_t>(Renderer_Shader::max)>& GetShaders();
static std::array<std::shared_ptr<RHI_Buffer>, static_cast<uint32_t>(Renderer_Buffer::Max)>& GetStructuredBuffers();
static std::array<std::shared_ptr<RHI_Sampler>, static_cast<uint32_t>(Renderer_Sampler::Max)>& GetSamplers();

// get individual
static RHI_RasterizerState* GetRasterizerState(const Renderer_RasterizerState type);
static RHI_DepthStencilState* GetDepthStencilState(const Renderer_DepthStencilState type);
static RHI_BlendState* GetBlendState(const Renderer_BlendState type);
static RHI_Texture* GetRenderTarget(const Renderer_RenderTarget type);
static RHI_Shader* GetShader(const Renderer_Shader type);
static RHI_Sampler* GetSampler(const Renderer_Sampler type);
static RHI_Buffer* GetBuffer(const Renderer_Buffer type);
static RHI_Texture* GetStandardTexture(const Renderer_StandardTexture type);
static std::shared_ptr<Mesh>& GetStandardMesh(const MeshType type);
Expand Down Expand Up @@ -193,6 +193,7 @@ namespace spartan
// bindless
static void BindlessUpdateMaterialsParameters(RHI_CommandList* cmd_list);
static void BindlessUpdateLights(RHI_CommandList* cmd_lis);
static void BindlessUpdateSamplers();

// misc
static std::unordered_map<Renderer_Entity, std::vector<std::shared_ptr<Entity>>> m_renderables;
Expand Down
15 changes: 8 additions & 7 deletions runtime/Rendering/Renderer_Resources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ namespace spartan
}
}

RHI_Device::UpdateBindlessResources(nullptr, nullptr, nullptr, &samplers);
Renderer::BindlessUpdateSamplers();
}

void Renderer::CreateRenderTargets(const bool create_render, const bool create_output, const bool create_dynamic)
Expand Down Expand Up @@ -266,7 +266,6 @@ namespace spartan
render_target(Renderer_RenderTarget::skysphere) = make_shared<RHI_Texture>(RHI_Texture_Type::Type2D, 4096, 4096, 1, mip_count, RHI_Format::R11G11B10_Float, flags | RHI_Texture_PerMipViews, "skysphere");
}

RHI_Device::QueueWaitAll();
RHI_FidelityFX::Resize(GetResolutionRender(), GetResolutionOutput());
}

Expand Down Expand Up @@ -622,6 +621,11 @@ namespace spartan
return buffers;
}

array<shared_ptr<RHI_Sampler>, static_cast<uint32_t>(Renderer_Sampler::Max)>& Renderer::GetSamplers()
{
return samplers;
}

RHI_RasterizerState* Renderer::GetRasterizerState(const Renderer_RasterizerState type)
{
return rasterizer_states[static_cast<uint8_t>(type)].get();
Expand All @@ -647,11 +651,6 @@ namespace spartan
return shaders[static_cast<uint8_t>(type)].get();
}

RHI_Sampler* Renderer::GetSampler(const Renderer_Sampler type)
{
return samplers[static_cast<uint8_t>(type)].get();
}

RHI_Buffer* Renderer::GetBuffer(const Renderer_Buffer type)
{
return buffers[static_cast<uint8_t>(type)].get();
Expand All @@ -676,4 +675,6 @@ namespace spartan
{
return standard_material;
}


}

0 comments on commit 5213be8

Please sign in to comment.