segregated descriptor set from pipeline (prerequisite for global/shared pipelines)

This commit is contained in:
ecker 2026-05-09 20:55:22 -05:00
parent 5f5bc08068
commit c62240641a
12 changed files with 212 additions and 186 deletions

View File

@ -21,19 +21,27 @@ namespace ext {
VkPipeline pipeline = VK_NULL_HANDLE;
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE;
VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
GraphicDescriptor descriptor = {};
uf::stl::vector<VkStridedDeviceAddressRegionKHR> sbtEntries;
void initialize( const Graphic& graphic );
void initialize( const Graphic& graphic, const GraphicDescriptor& descriptor );
void record( const Graphic& graphic, VkCommandBuffer, size_t = 0, size_t = 0, size_t = 0 ) const;
void destroy();
};
struct UF_API DescriptorSet : public Buffers {
bool aliased = false;
Device* device = NULL;
VkDescriptorSet descriptorSet = {};
GraphicDescriptor descriptor = {};
struct {
uf::Serializer json;
uf::stl::string type = "";
bool process = true;
bool rebuild = false;
bool built = false;
bool process = true;
} metadata;
void initialize( const Graphic& graphic );
@ -43,7 +51,7 @@ namespace ext {
void record( const Graphic& graphic, VkCommandBuffer, size_t = 0, size_t = 0, size_t = 0 ) const;
void record( const Graphic& graphic, const GraphicDescriptor& descriptor, VkCommandBuffer, size_t = 0, size_t = 0, size_t = 0 ) const;
void destroy();
void collectBuffers( const Shader& shader, const RenderMode& renderMode, const Graphic& graphic, const std::function<void(const Buffer&)>& lambda ) const;
};
@ -83,7 +91,9 @@ namespace ext {
bool initialized = false;
bool process = true;
Material material = {};
uf::stl::unordered_map<GraphicDescriptor, Pipeline> pipelines;
uf::stl::unordered_map<GraphicDescriptor, DescriptorSet> descriptorSets;
struct {
uf::stl::unordered_map<uf::stl::string, size_t> buffers;
@ -96,6 +106,9 @@ namespace ext {
~Graphic();
void initialize( const uf::stl::string& = "" );
void initialize( const GraphicDescriptor& );
void update();
void update( const GraphicDescriptor& );
void destroy();
// raster
@ -105,17 +118,22 @@ namespace ext {
void generateBottomAccelerationStructures();
void generateTopAccelerationStructure( const uf::stl::vector<uf::renderer::Graphic*>&, const uf::stl::vector<pod::Instance>&, const uf::stl::vector<pod::Matrix4f>& );
bool hasPipeline( const GraphicDescriptor& descriptor ) const;
void initializePipeline();
Pipeline& initializePipeline( const GraphicDescriptor& descriptor, bool update = true );
Pipeline& initializePipeline( const GraphicDescriptor& descriptor );
bool hasPipeline( const GraphicDescriptor& descriptor ) const;
Pipeline& getPipeline();
const Pipeline& getPipeline() const;
Pipeline& getPipeline( const GraphicDescriptor& descriptor );
const Pipeline& getPipeline( const GraphicDescriptor& descriptor ) const;
void updatePipelines();
void initializeDescriptorSet();
DescriptorSet& initializeDescriptorSet( const GraphicDescriptor& descriptor );
bool hasDescriptorSet( const GraphicDescriptor& descriptor ) const;
DescriptorSet& getDescriptorSet();
const DescriptorSet& getDescriptorSet() const;
DescriptorSet& getDescriptorSet( const GraphicDescriptor& descriptor );
const DescriptorSet& getDescriptorSet( const GraphicDescriptor& descriptor ) const;
void record( VkCommandBuffer commandBuffer, size_t pass = 0, size_t draw = 0, size_t offset = 0 ) const;
void record( VkCommandBuffer commandBuffer, const GraphicDescriptor& descriptor, size_t pass = 0, size_t draw = 0, size_t offset = 0 ) const;

View File

@ -215,7 +215,7 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
#endif
} else {
graphic.initializeMesh( mesh );
graphic.getPipeline().update( graphic );
graphic.update();
}
if ( payload.free ) {

View File

@ -51,8 +51,8 @@ void ext::PlayerModelBehavior::tick( uf::Object& self ) {
this->process([&](uf::Entity* entity){
if ( !entity->hasComponent<uf::Graphic>() ) return;
auto& graphic = entity->getComponent<uf::Graphic>();
auto& pipeline = graphic.getPipeline();
pipeline.metadata.process = !metadata.hide;
auto& descriptorSet = graphic.getDescriptorSet();
descriptorSet.metadata.process = !metadata.hide;
metadata.set = true;
});
metadata.set = true;

View File

@ -245,7 +245,7 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
graphic.descriptor.bind.height = renderMode.height > 0 ? renderMode.height : uf::renderer::settings::height;
graphic.descriptor.bind.point = VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR;
graphic.descriptor.pipeline = uf::renderer::settings::pipelines::names::rt;
graphic.getPipeline().update( graphic );
graphic.update();
}
#else
{
@ -288,7 +288,7 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
graphic.descriptor.bind.height = image.height;
graphic.descriptor.bind.point = VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR;
graphic.getPipeline().update( graphic );
graphic.update();
if ( blitter.material.hasShader("fragment") ) {
auto& shader = blitter.material.getShader("fragment");

View File

@ -1245,7 +1245,7 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic
if ( previousTextures[i] != graphic.material.textures[i].image ) shouldUpdate = true;
}
if ( shouldUpdate ) {
graphic.updatePipelines();
// graphic.updatePipelines();
metadata.shader.invalidated = false;
}

View File

@ -236,7 +236,9 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
//descriptor.pipeline = "lighting";
auto& pipeline = blitter.getPipeline( descriptor );
auto& descriptorSet = blitter.getDescriptorSet( descriptor );
pipeline.record( blitter, commandBuffer );
descriptorSet.record( blitter, commandBuffer );
}
// generate mipmaps
@ -264,7 +266,9 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
descriptor.pipeline = "mipmap";
auto& pipeline = blitter.getPipeline( descriptor );
auto& descriptorSet = blitter.getDescriptorSet( descriptor );
pipeline.record( blitter, commandBuffer );
descriptorSet.record( blitter, commandBuffer );
}
}
#else

View File

@ -663,11 +663,7 @@ void ext::fsr::initialize() {
blitter.descriptor.bind.height = uf::renderer::settings::height;
blitter.descriptor.bind.point = VK_PIPELINE_BIND_POINT_COMPUTE;
if ( !blitter.hasPipeline( blitter.descriptor ) ) {
blitter.initializePipeline( blitter.descriptor );
} else if ( blitter.hasPipeline( blitter.descriptor ) ){
blitter.getPipeline( blitter.descriptor ).update( blitter, blitter.descriptor );
}
blitter.update( blitter.descriptor );
}
ext::fsr::initialized = true;
@ -763,11 +759,7 @@ void ext::fsr::tick() {
blitter.descriptor.bind.width = displaySize.x;
blitter.descriptor.bind.height = displaySize.y;
if ( !blitter.hasPipeline( blitter.descriptor ) ) {
blitter.initializePipeline( blitter.descriptor );
} else if ( blitter.hasPipeline( blitter.descriptor ) ){
blitter.getPipeline( blitter.descriptor ).update( blitter, blitter.descriptor );
}
blitter.update( blitter.descriptor );
}
}

View File

@ -40,7 +40,6 @@ void ext::vulkan::Pipeline::initialize( const Graphic& graphic ) {
void ext::vulkan::Pipeline::initialize( const Graphic& graphic, const GraphicDescriptor& descriptor ) {
this->device = graphic.device;
this->descriptor = descriptor;
this->metadata.type = descriptor.pipeline;
Device& device = *graphic.device;
auto shaders = graphic.material.getShaders( descriptor.pipeline );
@ -80,22 +79,6 @@ void ext::vulkan::Pipeline::initialize( const Graphic& graphic, const GraphicDes
offset += len;
}
}
/*
for ( auto& descriptor : descriptorSetLayoutBindings ) {
if ( descriptorTypes.count( descriptor.descriptorType ) < 0 ) descriptorTypes[descriptor.descriptorType] = 0;
descriptorTypes[descriptor.descriptorType] += descriptor.descriptorCount;
}
for ( auto pair : descriptorTypes ) {
poolSizes.emplace_back(ext::vulkan::initializers::descriptorPoolSize(pair.first, pair.second));
}
VkDescriptorPoolCreateInfo descriptorPoolInfo = ext::vulkan::initializers::descriptorPoolCreateInfo(
poolSizes.size(),
poolSizes.data(),
1
);
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool));
VK_REGISTER_HANDLE( descriptorPool );
*/
VkDescriptorSetLayoutCreateInfo descriptorLayout = ext::vulkan::initializers::descriptorSetLayoutCreateInfo(
descriptorSetLayoutBindings.data(),
@ -104,17 +87,6 @@ void ext::vulkan::Pipeline::initialize( const Graphic& graphic, const GraphicDes
VK_CHECK_RESULT(vkCreateDescriptorSetLayout( device, &descriptorLayout, nullptr, &descriptorSetLayout ));
VK_REGISTER_HANDLE( descriptorSetLayout );
UF_ASSERT(device.descriptorAllocator.allocate( &descriptorSet, descriptorSetLayout ));
/*
VkDescriptorSetAllocateInfo allocInfo = ext::vulkan::initializers::descriptorSetAllocateInfo(
descriptorPool,
&descriptorSetLayout,
1
);
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet));
*/
VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = ext::vulkan::initializers::pipelineLayoutCreateInfo(
&descriptorSetLayout,
1
@ -401,9 +373,6 @@ PIPELINE_INITIALIZATION_INVALID:
return;
}
void ext::vulkan::Pipeline::record( const Graphic& graphic, VkCommandBuffer commandBuffer, size_t pass, size_t draw, size_t offset ) const {
return record( graphic, descriptor, commandBuffer, pass, draw, offset );
}
void ext::vulkan::Pipeline::record( const Graphic& graphic, const GraphicDescriptor& descriptor, VkCommandBuffer commandBuffer, size_t pass, size_t draw, size_t offset ) const {
auto shaders = graphic.material.getShaders( descriptor.pipeline );
// create dynamic offset ranges
@ -448,6 +417,91 @@ void ext::vulkan::Pipeline::record( const Graphic& graphic, const GraphicDescrip
vkCmdPushConstants( commandBuffer, pipelineLayout, shader->descriptor.stage, 0, size, data );
}
}
}
// Bind the rendering pipeline
// The pipeline (state object) contains all states of the rendering pipeline, binding it will set all the states specified at pipeline creation time
vkCmdBindPipeline(commandBuffer, (VkPipelineBindPoint) descriptor.bind.point, pipeline);
}
void ext::vulkan::Pipeline::destroy() {
if ( aliased ) return;
/*
if ( descriptorPool != VK_NULL_HANDLE) {
vkDestroyDescriptorPool( *device, descriptorPool, nullptr );
VK_UNREGISTER_HANDLE( descriptorPool );
descriptorPool = VK_NULL_HANDLE;
}
*/
if ( pipelineLayout != VK_NULL_HANDLE ) {
vkDestroyPipelineLayout( *device, pipelineLayout, nullptr );
VK_UNREGISTER_HANDLE( pipelineLayout );
pipelineLayout = VK_NULL_HANDLE;
}
if ( pipeline != VK_NULL_HANDLE ) {
vkDestroyPipeline( *device, pipeline, nullptr );
VK_UNREGISTER_HANDLE( pipeline );
pipeline = VK_NULL_HANDLE;
}
if ( descriptorSetLayout != VK_NULL_HANDLE ) {
vkDestroyDescriptorSetLayout( *device, descriptorSetLayout, nullptr );
VK_UNREGISTER_HANDLE( descriptorSetLayout );
descriptorSetLayout = VK_NULL_HANDLE;
}
// if ( settings::experimental::dedicatedThread ) ext::vulkan::states::rebuild = true;
/*
if ( ext::vulkan::hasRenderMode(descriptor.renderMode, true) ) {
RenderMode& renderMode = ext::vulkan::getRenderMode(descriptor.renderMode, true);
renderMode.rebuild = true;
}
*/
}
void ext::vulkan::DescriptorSet::initialize( const Graphic& graphic ) {
initialize( graphic, graphic.descriptor );
}
void ext::vulkan::DescriptorSet::initialize( const Graphic& graphic, const GraphicDescriptor& descriptor ) {
if ( descriptorSet != VK_NULL_HANDLE ) return;
this->device = graphic.device;
this->descriptor = descriptor;
auto& pipeline = graphic.getPipeline( descriptor );
UF_ASSERT(device->descriptorAllocator.allocate( &descriptorSet, pipeline.descriptorSetLayout ));
}
void ext::vulkan::DescriptorSet::record( const Graphic& graphic, VkCommandBuffer commandBuffer, size_t pass, size_t draw, size_t offset ) const {
return record( graphic, descriptor, commandBuffer, pass, draw, offset );
}
void ext::vulkan::DescriptorSet::record( const Graphic& graphic, const GraphicDescriptor& descriptor, VkCommandBuffer commandBuffer, size_t pass, size_t draw, size_t offset ) const {
auto shaders = graphic.material.getShaders( descriptor.pipeline );
auto& pipeline = graphic.getPipeline( descriptor );
// create dynamic offset ranges
STATIC_THREAD_LOCAL(uf::stl::vector<uint32_t>, dynamicOffsets);
RenderMode& renderMode = ext::vulkan::getRenderMode(descriptor.renderMode, true);
bool bound = false;
for ( auto* shader : shaders ) {
// compute shaders
if ( shader->descriptor.stage == VK_SHADER_STAGE_COMPUTE_BIT ) {
if ( descriptor.bind.point == VK_PIPELINE_BIND_POINT_COMPUTE ) bound = true;
else continue;
// raytrace shaders
} else if (
shader->descriptor.stage == VK_SHADER_STAGE_RAYGEN_BIT_KHR ||
shader->descriptor.stage == VK_SHADER_STAGE_MISS_BIT_KHR ||
shader->descriptor.stage == VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR ||
shader->descriptor.stage == VK_SHADER_STAGE_ANY_HIT_BIT_KHR ||
shader->descriptor.stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR
) {
if ( descriptor.bind.point == VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR ) bound = true;
else continue;
// anything else
} else {
if ( descriptor.bind.point == VK_PIPELINE_BIND_POINT_GRAPHICS ) bound = true;
else continue;
}
dynamicOffsets.insert( dynamicOffsets.end(), shader->metadata.dynamicRanges.begin(), shader->metadata.dynamicRanges.end() );
}
@ -463,13 +517,10 @@ void ext::vulkan::Pipeline::record( const Graphic& graphic, const GraphicDescrip
// Bind descriptor sets describing shader binding points
#if VK_UBO_USE_N_BUFFERS
vkCmdBindDescriptorSets(commandBuffer, (VkPipelineBindPoint) descriptor.bind.point, pipelineLayout, 0, 1, &descriptorSet, dynamicOffsets.size(), dynamicOffsets.data());
vkCmdBindDescriptorSets(commandBuffer, (VkPipelineBindPoint) descriptor.bind.point, pipeline.pipelineLayout, 0, 1, &descriptorSet, dynamicOffsets.size(), dynamicOffsets.data());
#else
vkCmdBindDescriptorSets(commandBuffer, (VkPipelineBindPoint) descriptor.bind.point, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);
vkCmdBindDescriptorSets(commandBuffer, (VkPipelineBindPoint) descriptor.bind.point, pipeline.pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);
#endif
// Bind the rendering pipeline
// The pipeline (state object) contains all states of the rendering pipeline, binding it will set all the states specified at pipeline creation time
vkCmdBindPipeline(commandBuffer, (VkPipelineBindPoint)descriptor.bind.point, pipeline);
uint32_t width = descriptor.bind.width ? descriptor.bind.width : ext::vulkan::settings::width;
uint32_t height = descriptor.bind.height ? descriptor.bind.height : ext::vulkan::settings::height;
@ -478,10 +529,10 @@ void ext::vulkan::Pipeline::record( const Graphic& graphic, const GraphicDescrip
if ( descriptor.bind.point == VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR ) {
uf::renderer::vkCmdTraceRaysKHR(
commandBuffer,
&sbtEntries[0],
&sbtEntries[1],
&sbtEntries[2],
&sbtEntries[3],
&pipeline.sbtEntries[0],
&pipeline.sbtEntries[1],
&pipeline.sbtEntries[2],
&pipeline.sbtEntries[3],
width,
height,
1
@ -504,12 +555,12 @@ void ext::vulkan::Pipeline::record( const Graphic& graphic, const GraphicDescrip
}
}
}
void ext::vulkan::Pipeline::update( const Graphic& graphic ) {
void ext::vulkan::DescriptorSet::update( const Graphic& graphic ) {
return this->update( graphic, descriptor );
}
void ext::vulkan::Pipeline::update( const Graphic& graphic, const GraphicDescriptor& descriptor ) {
void ext::vulkan::DescriptorSet::update( const Graphic& graphic, const GraphicDescriptor& descriptor ) {
//
if ( descriptorSet == VK_NULL_HANDLE ) return;
if ( descriptorSet == VK_NULL_HANDLE ) this->initialize( graphic, descriptor );
this->descriptor = descriptor;
RenderMode& renderMode = ext::vulkan::getRenderMode(descriptor.renderMode, true);
@ -895,7 +946,7 @@ PIPELINE_UPDATE_INVALID:
});
return;
}
void ext::vulkan::Pipeline::collectBuffers( const Shader& shader, const RenderMode& renderMode, const Graphic& graphic, const std::function<void(const Buffer&)>& lambda ) const {
void ext::vulkan::DescriptorSet::collectBuffers( const Shader& shader, const RenderMode& renderMode, const Graphic& graphic, const std::function<void(const Buffer&)>& lambda ) const {
// add aliased-by-name buffers
for ( auto& descriptor : shader.metadata.aliases.buffers ) {
auto matches = uf::string::match(descriptor.name, R"(/^(.+?)\[(\d+)\]$/)");
@ -924,37 +975,9 @@ void ext::vulkan::Pipeline::collectBuffers( const Shader& shader, const RenderMo
// add per-graphics buffers
for ( auto& buffer : graphic.buffers ) lambda( buffer );
}
void ext::vulkan::Pipeline::destroy() {
if ( aliased ) return;
if ( descriptorPool != VK_NULL_HANDLE) {
vkDestroyDescriptorPool( *device, descriptorPool, nullptr );
VK_UNREGISTER_HANDLE( descriptorPool );
descriptorPool = VK_NULL_HANDLE;
}
if ( pipelineLayout != VK_NULL_HANDLE ) {
vkDestroyPipelineLayout( *device, pipelineLayout, nullptr );
VK_UNREGISTER_HANDLE( pipelineLayout );
pipelineLayout = VK_NULL_HANDLE;
}
if ( pipeline != VK_NULL_HANDLE ) {
vkDestroyPipeline( *device, pipeline, nullptr );
VK_UNREGISTER_HANDLE( pipeline );
pipeline = VK_NULL_HANDLE;
}
if ( descriptorSetLayout != VK_NULL_HANDLE ) {
vkDestroyDescriptorSetLayout( *device, descriptorSetLayout, nullptr );
VK_UNREGISTER_HANDLE( descriptorSetLayout );
descriptorSetLayout = VK_NULL_HANDLE;
}
// if ( settings::experimental::dedicatedThread ) ext::vulkan::states::rebuild = true;
/*
if ( ext::vulkan::hasRenderMode(descriptor.renderMode, true) ) {
RenderMode& renderMode = ext::vulkan::getRenderMode(descriptor.renderMode, true);
renderMode.rebuild = true;
}
*/
void ext::vulkan::DescriptorSet::destroy() {
// no-op
}
uf::stl::vector<const ext::vulkan::Shader*> ext::vulkan::Material::getShaders( const uf::stl::string& type ) const {
@ -1074,26 +1097,28 @@ void ext::vulkan::Graphic::initialize( const uf::stl::string& renderModeName ) {
if ( this->accelerationStructures.tops.empty() ) this->accelerationStructures.tops.resize(2);
}
void ext::vulkan::Graphic::initializePipeline() {
initializePipeline( this->descriptor, false );
void ext::vulkan::Graphic::initialize( const GraphicDescriptor& descriptor ) {
update( descriptor );
}
ext::vulkan::Pipeline& ext::vulkan::Graphic::initializePipeline( const GraphicDescriptor& descriptor, bool update ) {
auto& pipeline = pipelines[descriptor];
pipeline.initialize(*this, descriptor);
pipeline.update(*this, descriptor);
void ext::vulkan::Graphic::update() {
update( this->descriptor );
}
void ext::vulkan::Graphic::update( const GraphicDescriptor& descriptor ) {
initializePipeline( descriptor );
initializeDescriptorSet( descriptor );
initialized = true;
material.validate();
}
void ext::vulkan::Graphic::initializePipeline() {
initializePipeline( this->descriptor );
}
ext::vulkan::Pipeline& ext::vulkan::Graphic::initializePipeline( const GraphicDescriptor& descriptor ) {
auto& pipeline = pipelines[descriptor];
pipeline.initialize(*this, descriptor);
return pipeline;
}
void ext::vulkan::Graphic::initializeMesh( uf::Mesh& mesh, bool buffer ) {
// generate indices if not found
// if ( mesh.index.count == 0 ) mesh.generateIndices();
// generate indirect data if not found
// if ( mesh.indirect.count == 0 ) mesh.generateIndirect();
// ensure our descriptors are proper
mesh.updateDescriptor();
// copy descriptors
@ -1146,11 +1171,6 @@ void ext::vulkan::Graphic::initializeMesh( uf::Mesh& mesh, bool buffer ) {
}
}
bool ext::vulkan::Graphic::updateMesh( uf::Mesh& mesh ) {
// generate indices if not found
// if ( mesh.index.count == 0 ) mesh.generateIndices();
// generate indirect data if not found
// if ( mesh.indirect.count == 0 ) mesh.generateIndirect();
// ensure our descriptors are proper
mesh.updateDescriptor();
descriptor.inputs.vertex = mesh.vertex;
@ -1824,8 +1844,35 @@ const ext::vulkan::Pipeline& ext::vulkan::Graphic::getPipeline( const GraphicDes
if ( !hasPipeline(descriptor) ) UF_EXCEPTION("does not have pipeline");
return pipelines.at(descriptor);
}
void ext::vulkan::Graphic::updatePipelines() {
for ( auto pair : this->pipelines ) pair.second.update( *this );
bool ext::vulkan::Graphic::hasDescriptorSet( const GraphicDescriptor& descriptor ) const {
return descriptorSets.count( descriptor ) > 0;
}
void ext::vulkan::Graphic::initializeDescriptorSet() {
initializeDescriptorSet( this->descriptor );
}
ext::vulkan::DescriptorSet& ext::vulkan::Graphic::initializeDescriptorSet( const GraphicDescriptor& descriptor ) {
auto& descriptorSet = descriptorSets[descriptor];
descriptorSet.initialize(*this, descriptor);
descriptorSet.update(*this, descriptor);
return descriptorSet;
}
ext::vulkan::DescriptorSet& ext::vulkan::Graphic::getDescriptorSet() {
return getDescriptorSet( descriptor );
}
const ext::vulkan::DescriptorSet& ext::vulkan::Graphic::getDescriptorSet() const {
return getDescriptorSet( descriptor );
}
ext::vulkan::DescriptorSet& ext::vulkan::Graphic::getDescriptorSet( const GraphicDescriptor& descriptor ) {
if ( !hasDescriptorSet(descriptor) ) return initializeDescriptorSet( descriptor );
return descriptorSets[descriptor];
}
const ext::vulkan::DescriptorSet& ext::vulkan::Graphic::getDescriptorSet( const GraphicDescriptor& descriptor ) const {
if ( !hasDescriptorSet(descriptor) ) UF_EXCEPTION("does not have descriptor set");
return descriptorSets.at(descriptor);
}
void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer, size_t pass, size_t draw, size_t offset ) const {
return this->record( commandBuffer, descriptor, pass, draw, offset );
@ -1836,14 +1883,18 @@ void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer, const GraphicD
//UF_MSG_DEBUG("{} has no valid pipeline ({}:{}:{})", (void*) this, descriptor.renderMode, descriptor.renderTarget, descriptor.pipeline);
return;
}
auto& pipeline = this->getPipeline( descriptor );
if ( pipeline.descriptorSet == VK_NULL_HANDLE ) {
//UF_MSG_DEBUG("{} has no valid pipeline descriptor set ({}:{}:{})", (void*) this, descriptor.renderMode, descriptor.renderTarget, descriptor.pipeline);
if ( !this->hasDescriptorSet( descriptor ) ) {
//UF_MSG_DEBUG("{} has no valid descriptor set ({}:{}:{})", (void*) this, descriptor.renderMode, descriptor.renderTarget, descriptor.pipeline);
return;
}
if ( !pipeline.metadata.process ) return;
pipeline.record(*this, descriptor, commandBuffer, pass, draw, offset);
auto& pipeline = this->getPipeline( descriptor );
auto& descriptorSet = this->getDescriptorSet( descriptor );
if ( !descriptorSet.metadata.process ) return;
pipeline.record( *this, commandBuffer, pass, draw, offset );
descriptorSet.record( *this, descriptor, commandBuffer, pass, draw, offset );
auto shaders = material.getShaders( descriptor.pipeline );
for ( auto* shader : shaders ) {
@ -1979,10 +2030,11 @@ void ext::vulkan::Graphic::destroy() {
}
accelerationStructures.tops.clear();
}
for ( auto& pair : pipelines ) {
pair.second.destroy();
}
for ( auto& pair : pipelines ) pair.second.destroy();
pipelines.clear();
for ( auto& pair : descriptorSets ) pair.second.destroy();
descriptorSets.clear();
material.destroy();
ext::vulkan::Buffers::destroy();

View File

@ -351,7 +351,7 @@ void ext::vulkan::RenderMode::bindPipelines( const uf::stl::vector<ext::vulkan::
size_t shaders = 0;
for ( auto& shader : graphic.material.shaders ) if ( shader.metadata.pipeline == descriptor.pipeline ) ++shaders;
if ( shaders == 0 ) continue;
graphic.initializePipeline( descriptor );
graphic.update( descriptor );
}
}
}

View File

@ -525,12 +525,8 @@ void ext::vulkan::DeferredRenderMode::build( bool resized ) {
// (re)initialize pipelines
{
ext::vulkan::GraphicDescriptor descriptor = blitter.descriptor;
if ( blitter.hasPipeline( blitter.descriptor ) ){
blitter.getPipeline( blitter.descriptor ).update( blitter, blitter.descriptor );
} else {
blitter.initializePipeline( blitter.descriptor );
}
blitter.update( blitter.descriptor );
descriptor.renderMode = "";
descriptor.bind.width = width;
@ -546,11 +542,7 @@ void ext::vulkan::DeferredRenderMode::build( bool resized ) {
descriptor.subpass = 0;
descriptor.bind.point = VK_PIPELINE_BIND_POINT_COMPUTE;
}
if ( blitter.hasPipeline( descriptor ) ) {
blitter.getPipeline( descriptor ).update( blitter, descriptor );
} else {
blitter.initializePipeline( descriptor );
}
blitter.update( descriptor );
}
if ( settings::pipelines::bloom ) {
@ -558,11 +550,7 @@ void ext::vulkan::DeferredRenderMode::build( bool resized ) {
descriptor.pipeline = "bloom-down";
descriptor.subpass = 0;
descriptor.bind.point = VK_PIPELINE_BIND_POINT_COMPUTE;
if ( blitter.hasPipeline( descriptor ) ) {
blitter.getPipeline( descriptor ).update( blitter, descriptor );
} else {
blitter.initializePipeline( descriptor );
}
blitter.update( descriptor );
}
if ( settings::pipelines::bloom ) {
@ -570,11 +558,7 @@ void ext::vulkan::DeferredRenderMode::build( bool resized ) {
descriptor.pipeline = "bloom-up";
descriptor.subpass = 0;
descriptor.bind.point = VK_PIPELINE_BIND_POINT_COMPUTE;
if ( blitter.hasPipeline( descriptor ) ) {
blitter.getPipeline( descriptor ).update( blitter, descriptor );
} else {
blitter.initializePipeline( descriptor );
}
blitter.update( descriptor );
}
if ( settings::pipelines::dof ) {
@ -582,11 +566,7 @@ void ext::vulkan::DeferredRenderMode::build( bool resized ) {
descriptor.pipeline = "dof-down";
descriptor.subpass = 0;
descriptor.bind.point = VK_PIPELINE_BIND_POINT_COMPUTE;
if ( blitter.hasPipeline( descriptor ) ) {
blitter.getPipeline( descriptor ).update( blitter, descriptor );
} else {
blitter.initializePipeline( descriptor );
}
blitter.update( descriptor );
}
if ( settings::pipelines::dof ) {
@ -594,11 +574,7 @@ void ext::vulkan::DeferredRenderMode::build( bool resized ) {
descriptor.pipeline = "dof-up";
descriptor.subpass = 0;
descriptor.bind.point = VK_PIPELINE_BIND_POINT_COMPUTE;
if ( blitter.hasPipeline( descriptor ) ) {
blitter.getPipeline( descriptor ).update( blitter, descriptor );
} else {
blitter.initializePipeline( descriptor );
}
blitter.update( descriptor );
}
if ( settings::pipelines::culling ) {
@ -606,11 +582,7 @@ void ext::vulkan::DeferredRenderMode::build( bool resized ) {
descriptor.pipeline = "depth-pyramid";
descriptor.subpass = 0;
descriptor.bind.point = VK_PIPELINE_BIND_POINT_COMPUTE;
if ( blitter.hasPipeline( descriptor ) ) {
blitter.getPipeline( descriptor ).update( blitter, descriptor );
} else {
blitter.initializePipeline( descriptor );
}
blitter.update( descriptor );
}
}
}

View File

@ -371,11 +371,7 @@ void ext::vulkan::RenderTargetRenderMode::build( bool resized ) {
blitter.descriptor.bind.width = width;
blitter.descriptor.bind.height = height;
if ( !blitter.hasPipeline( blitter.descriptor ) ) {
blitter.initializePipeline( blitter.descriptor );
} else if ( blitter.hasPipeline( blitter.descriptor ) ){
blitter.getPipeline( blitter.descriptor ).update( blitter, blitter.descriptor );
}
blitter.update( blitter.descriptor );
}
if ( metadata.type == uf::renderer::settings::pipelines::names::vxgi ) {
@ -383,11 +379,7 @@ void ext::vulkan::RenderTargetRenderMode::build( bool resized ) {
//descriptor.pipeline = "lighting";
descriptor.subpass = -1;
descriptor.bind.point = VK_PIPELINE_BIND_POINT_COMPUTE;
if ( blitter.hasPipeline( descriptor ) ) {
blitter.getPipeline( descriptor ).update( blitter, descriptor );
} else {
blitter.initializePipeline( descriptor );
}
blitter.update( descriptor );
}
if ( metadata.type == uf::renderer::settings::pipelines::names::vxgi ) {
@ -395,11 +387,7 @@ void ext::vulkan::RenderTargetRenderMode::build( bool resized ) {
descriptor.pipeline = "mipmap";
descriptor.subpass = -1;
descriptor.bind.point = VK_PIPELINE_BIND_POINT_COMPUTE;
if ( blitter.hasPipeline( descriptor ) ) {
blitter.getPipeline( descriptor ).update( blitter, descriptor );
} else {
blitter.initializePipeline( descriptor );
}
blitter.update( descriptor );
}
}

View File

@ -519,7 +519,7 @@ void ext::vulkan::tick() {
if ( entity->hasComponent<uf::Graphic>() ) {
ext::vulkan::Graphic& graphic = entity->getComponent<uf::Graphic>();
if ( graphic.initialized || !graphic.process || graphic.initialized ) continue;
graphic.initializePipeline();
graphic.update();
ext::vulkan::states::rebuild = true;
}
}
@ -527,7 +527,7 @@ void ext::vulkan::tick() {
auto tasks = uf::thread::schedule( settings::invariant::multithreadedRecording );
for ( auto& renderMode : renderModes ) { if ( !renderMode || (renderMode->executed && !renderMode->execute) ) continue;
if ( ext::vulkan::states::rebuild || renderMode->rebuild ) tasks.queue([renderMode]{
if ( settings::invariant::individualPipelines ) renderMode->bindPipelines();
renderMode->bindPipelines();
renderMode->createCommandBuffers();
});
else if ( renderMode->rerecord ) tasks.queue([renderMode]{