Compare commits

...

3 Commits

27 changed files with 405 additions and 252 deletions

View File

@ -8,9 +8,9 @@
"useLightmaps": false,
"max": 32,
"shadows": {
"enabled": false, // to-do: fix
"enabled": true, // to-do: fix
"update": 4,
"max": 8,
"max": 16,
"samples": 2
},
"bloom": {

View File

@ -26,7 +26,7 @@
"bias": {
"constant": 1.25,
"slope": 1.75,
"shader": 0.000005 // 0.000005 //0.000000005
"shader": 0.00005 // 0.000005 //0.000000005
},
"radius": [0.5, 0],
"resolution": 1024,

View File

@ -1,11 +1,11 @@
{
"type": "Object",
"name": "Player: Model",
"ignore": true,
"ignore": false,
"import": "/model.json",
"assets": [
"/player/ben.glb"
// { "filename": "/player/bear/graph.json" }
// "/player/ben.glb"
{ "filename": "/player/bear/graph.json" }
],
"behaviors": [
"PlayerModelBehavior"
@ -22,7 +22,7 @@
},
"metadata": {
"track": true,
"hide": false,
"hide": true,
"graph": {
"debug": {
"print": {

View File

@ -102,6 +102,8 @@ int main(int argc, char** argv){
}
while ( client::ready && uf::ready ) {
++uf::time::frame;
#if UF_EXCEPTIONS
try {
#endif

View File

@ -29,6 +29,30 @@ namespace ext {
operator VkCommandBuffer() { return handle; }
};
struct DescriptorAllocator {
VkDevice device = VK_NULL_HANDLE;
VkDescriptorPool currentPool = VK_NULL_HANDLE;
uf::stl::vector<VkDescriptorPool> usedPools;
uf::stl::vector<VkDescriptorPoolSize> poolSizes = {
{ VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 4000 },
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 4000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2000 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 },
{ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 500 },
{ VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 100 }
};
void initialize( VkDevice );
void destroy();
VkDescriptorPool createPool();
bool allocate( VkDescriptorSet* set, VkDescriptorSetLayout layout );
};
struct Texture;
struct UF_API Device {
@ -69,6 +93,7 @@ namespace ext {
} extensions;
VkPipelineCache pipelineCache;
DescriptorAllocator descriptorAllocator;
uf::stl::vector<VkQueueFamilyProperties> queueFamilyProperties;

View File

@ -12,6 +12,8 @@ namespace ext {
struct Graphic;
struct UF_API Pipeline : public Buffers {
static uf::stl::unordered_map<GraphicDescriptor, Pipeline> pipelines;
bool aliased = false;
Device* device = NULL;
@ -19,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;
struct {
uf::Serializer json;
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();
};
uf::stl::string type = "";
bool process = true;
bool rebuild = false;
struct UF_API DescriptorSet : public Buffers {
bool aliased = false;
Device* device = NULL;
VkDescriptorSet descriptorSet = {};
GraphicDescriptor descriptor = {};
struct {
bool built = false;
bool process = true;
} metadata;
void initialize( const Graphic& graphic );
@ -42,9 +52,6 @@ namespace ext {
void record( const Graphic& graphic, const GraphicDescriptor& descriptor, VkCommandBuffer, size_t = 0, size_t = 0, size_t = 0 ) const;
void destroy();
uf::stl::vector<Shader*> getShaders( uf::stl::vector<Shader>&, const uf::stl::string& = "" );
uf::stl::vector<const Shader*> getShaders( const uf::stl::vector<Shader>&, const uf::stl::string& = "" ) const;
void collectBuffers( const Shader& shader, const RenderMode& renderMode, const Graphic& graphic, const std::function<void(const Buffer&)>& lambda ) const;
};
@ -61,6 +68,7 @@ namespace ext {
bool autoInitializeUniformBuffers = true;
bool autoInitializeUniformUserdatas = false;
uf::stl::unordered_map<uf::stl::string, size_t> shaders;
uf::stl::unordered_map<uf::stl::string, size_t> hashes;
} metadata;
void initialize( Device& device );
@ -73,6 +81,8 @@ namespace ext {
Shader& getShader( const uf::stl::string& type, const uf::stl::string& pipeline = "" );
const Shader& getShader( const uf::stl::string& type, const uf::stl::string& pipeline = "" ) const;
uf::stl::vector<const Shader*> getShaders( const uf::stl::string& = "" ) const;
bool validate();
};
@ -82,7 +92,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;
@ -95,6 +107,9 @@ namespace ext {
~Graphic();
void initialize( const uf::stl::string& = "" );
void initialize( const GraphicDescriptor& );
void update();
void update( const GraphicDescriptor& );
void destroy();
// raster
@ -104,17 +119,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

@ -430,6 +430,7 @@ namespace ext {
uf::stl::string renderMode = "";
uf::stl::string pipeline = "";
hash_t material = {};
uint32_t renderTarget = 0;
uint32_t subpass = 0;

View File

@ -733,7 +733,7 @@ void UF_API uf::initialize() {
}
void UF_API uf::tick() {
++uf::time::frame;
//++uf::time::frame;
static pod::Thread& threadMain = uf::thread::get(uf::thread::mainThreadName);
#if UF_THREAD_METRICS

View File

@ -201,8 +201,6 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
{filenames.vertex, uf::renderer::enums::Shader::VERTEX},
{filenames.fragment, uf::renderer::enums::Shader::FRAGMENT},
});
#if UF_USE_VULKAN
{
auto& shader = graphic.material.getShader("vertex");
@ -215,7 +213,7 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
#endif
} else {
graphic.initializeMesh( mesh );
graphic.getPipeline().update( graphic );
graphic.update();
}
if ( payload.free ) {

View File

@ -75,7 +75,7 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
}
camera.setProjection( uf::matrix::perspective( fov, raidou, range.x, range.y ) );
}
// camera.update(true);
camera.update(true);
}
// sloppy
@ -668,7 +668,7 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
}
}
#endif
// camera.update(true);
camera.update(true);
#if UF_ENTITY_METADATA_USE_JSON
metadata.serialize(self, metadataJson);

View File

@ -51,12 +51,12 @@ 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;
if ( !graphic.initialized ) return;
auto& descriptorSet = graphic.getDescriptorSet();
descriptorSet.metadata.process = !metadata.hide;
metadata.set = true;
uf::renderer::states::rebuild = true;
});
metadata.set = true;
uf::renderer::states::rebuild = true;
}
void ext::PlayerModelBehavior::render( uf::Object& self ){}

View File

@ -235,7 +235,7 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
}
if ( metadata.renderer.full ) {
/* Update lights */ {
ext::ExtSceneBehavior::bindBuffers( *this, graphic, "ray:gen", uf::renderer::settings::pipelines::names::rt );
ext::ExtSceneBehavior::bindBuffers( *this, graphic, "", "ray:gen", uf::renderer::settings::pipelines::names::rt );
}
if ( !metadata.renderer.bound ) return;
#if !UF_USE_EXTERNAL_IMAGE
@ -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

@ -458,7 +458,7 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
auto/*&*/ graph = this->getGraph();
auto& controller = this->getController();
// auto& camera = controller.getComponent<uf::Camera>();
auto& camera = this->getCamera( controller );
// auto& camera = this->getCamera( controller );
auto& controllerMetadata = controller.getComponent<uf::Serializer>();
auto& controllerTransform = controller.getComponent<pod::Transform<>>();
auto& metadata = this->getComponent<ext::ExtSceneBehavior::Metadata>();
@ -524,8 +524,6 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
auto& storage = uf::graph::globalStorage ? uf::graph::storage : this->getComponent<pod::Graph::Storage>();
auto/*&*/ graph = this->getGraph();
auto& controller = this->getController();
// auto& camera = controller.getComponent<uf::Camera>();
auto& camera = this->getCamera( controller );
auto& controllerMetadata = controller.getComponent<uf::Serializer>();
auto& controllerTransform = controller.getComponent<pod::Transform<>>();
auto& metadata = this->getComponent<ext::ExtSceneBehavior::Metadata>();
@ -919,9 +917,13 @@ void ext::ExtSceneBehavior::Metadata::deserialize( uf::Object& self, uf::Seriali
void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, const uf::stl::string& renderModeName, const uf::stl::string& shaderType, const uf::stl::string& shaderPipeline ) {
auto& renderMode = uf::renderer::getRenderMode(renderModeName, true);
bindBuffers( self, renderMode.getBlitter(), shaderType, shaderPipeline );
bindBuffers( self, renderMode.getBlitter(), renderMode, shaderType, shaderPipeline );
}
void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic& graphic, const uf::stl::string& shaderType, const uf::stl::string& shaderPipeline ) {
void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic& graphic, const uf::stl::string& renderModeName, const uf::stl::string& shaderType, const uf::stl::string& shaderPipeline ) {
auto& renderMode = uf::renderer::getRenderMode(renderModeName, true);
bindBuffers( self, graphic, renderMode, shaderType, shaderPipeline );
}
void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic& graphic, uf::renderer::RenderMode& renderMode, const uf::stl::string& shaderType, const uf::stl::string& shaderPipeline ) {
auto/*&*/ graph = this->getGraph();
auto& controller = this->getController();
// auto& camera = controller.getComponent<uf::Camera>();
@ -1245,7 +1247,9 @@ 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();
graphic.update();
renderMode.rebuild = true;
metadata.shader.invalidated = false;
}

View File

@ -83,7 +83,9 @@ namespace ext {
} framebuffer;
);
void bindBuffers( uf::Object&, const uf::stl::string& = "", const uf::stl::string& = "fragment", const uf::stl::string& = "deferred" );
void bindBuffers( uf::Object&, uf::renderer::Graphic&, const uf::stl::string& = "fragment", const uf::stl::string& = "deferred" );
void bindBuffers( uf::Object&, const uf::stl::string&, const uf::stl::string&, const uf::stl::string& );
void bindBuffers( uf::Object&, uf::renderer::Graphic&, const uf::stl::string&, const uf::stl::string&, const uf::stl::string& );
void bindBuffers( uf::Object&, uf::renderer::Graphic&, uf::renderer::RenderMode&, const uf::stl::string& = "compute", const uf::stl::string& = "deferred" );
}
}

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

@ -25,7 +25,10 @@ namespace {
auto& animation = storage.animations.map[name];
UF_ASSERT( animation.path != "" );
//UF_ASSERT( animation.path != "" );
if ( animation.path == "" ) {
return;
}
uf::Serializer json;
json.readFromFile( animation.path );

View File

@ -1511,8 +1511,6 @@ void uf::graph::render( pod::Graph::Storage& storage ) {
}
#endif
// if ( controller.getName() == "Player" ) UF_MSG_DEBUG("frame={}, camera={}, renderMode={}, {}", uf::time::frame, uf::matrix::toString( viewport.matrices[0].view ), renderMode->getName(), renderMode->getType() );
storage.buffers.camera.update( (const void*) &viewport, sizeof(pod::Camera::Viewports) );
#if UF_USE_VULKAN

View File

@ -64,7 +64,7 @@ const uf::Entity& uf::Scene::getController() const {
return scene.getController();
}
uf::Camera& uf::Scene::getCamera(uf::Entity& controller) {
uf::Camera& uf::Scene::getCamera( uf::Entity& controller ) {
// ???
/*
if ( auto currentRenderMode = uf::renderer::getCurrentRenderMode(); currentRenderMode && !currentRenderMode->getName().empty() ) {
@ -75,18 +75,21 @@ uf::Camera& uf::Scene::getCamera(uf::Entity& controller) {
auto& metadata = this->getComponent<uf::SceneBehavior::Metadata>();
#endif
auto uid = controller.getUid();
auto& cachedCamera = metadata.cache.cameras[uid].camera;
auto& lastFrame = metadata.cache.cameras[uid].lastFrame;
auto& cache = metadata.cache.cameras[uid];
auto& cachedCamera = cache.camera;
auto& lastFrame = cache.lastFrame;
if ( lastFrame != uf::time::frame ) {
auto& sourceCamera = controller.getComponent<uf::Camera>();
cachedCamera.setTransform(uf::transform::flatten(sourceCamera.getTransform()));
// update if camera wasn't already updated
//sourceCamera.update(true);
// copy all matrices
for ( auto i = 0; i < uf::camera::maxViews; ++i ) {
cachedCamera.setView(sourceCamera.getView(i), i);
cachedCamera.setProjection(sourceCamera.getProjection(i), i);
}
cachedCamera.update(true);
// flatten the transform in the event the parent transform updates later
cachedCamera.setTransform(uf::transform::flatten(cachedCamera.getTransform()));
lastFrame = uf::time::frame;
}
return cachedCamera;
@ -104,8 +107,9 @@ void uf::Scene::invalidateGraph() {
auto& metadata = this->getComponent<uf::SceneBehavior::Metadata>();
#endif
metadata.invalidationQueued = true;
/*
metadata.cache.controllers.clear();
metadata.cache.cameras.clear();
/*
metadata.tasks.serial.clear();
metadata.tasks.parallel.clear();

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

@ -2,6 +2,7 @@
#include <uf/ext/vulkan/vulkan.h>
#include <uf/ext/vulkan/device.h>
#include <uf/ext/vulkan/graphic.h>
#include <uf/ext/vulkan/initializers.h>
#include <uf/utils/window/window.h>
#include <uf/utils/string/ext.h>
@ -1178,8 +1179,8 @@ void ext::vulkan::Device::initialize() {
}
struct BaseStructure {
VkStructureType sType;
void* pNext;
VkStructureType sType;
void* pNext;
};
std::queue<void*> chain = {};
@ -1457,7 +1458,7 @@ void ext::vulkan::Device::initialize() {
if ( uf::io::exists( uf::io::root + "/cache/vulkan/cache.bin" ) ) {
uf::io::readAsBuffer( buffer, uf::io::root + "/cache/vulkan/cache.bin" );
pipelineCacheCreateInfo.initialDataSize = buffer.size();
pipelineCacheCreateInfo.pInitialData = buffer.data();
pipelineCacheCreateInfo.pInitialData = buffer.data();
}
VK_CHECK_RESULT(vkCreatePipelineCache( device, &pipelineCacheCreateInfo, nullptr, &this->pipelineCache));
@ -1507,6 +1508,10 @@ void ext::vulkan::Device::initialize() {
VK_REGISTER_HANDLE( allocator );
}
{
descriptorAllocator.initialize( logicalDevice );
}
{
vkGetBufferDeviceAddressKHR = reinterpret_cast<PFN_vkGetBufferDeviceAddressKHR>(vkGetDeviceProcAddr(device, "vkGetBufferDeviceAddressKHR"));
vkCmdBuildAccelerationStructuresKHR = reinterpret_cast<PFN_vkCmdBuildAccelerationStructuresKHR>(vkGetDeviceProcAddr(device, "vkCmdBuildAccelerationStructuresKHR"));
@ -1569,6 +1574,12 @@ void ext::vulkan::Device::destroy() {
VK_UNREGISTER_HANDLE( this->pipelineCache );
this->pipelineCache = nullptr;
}
for ( auto& pair : Pipeline::pipelines ) pair.second.destroy();
Pipeline::pipelines.clear();
descriptorAllocator.destroy();
for ( auto& pair : this->commandPool.graphics.container() ) {
vkDestroyCommandPool( this->logicalDevice, pair.second, nullptr );
VK_UNREGISTER_HANDLE( pair.second );
@ -1608,4 +1619,50 @@ void ext::vulkan::Device::destroy() {
VK_UNREGISTER_HANDLE( allocator );
}
void ext::vulkan::DescriptorAllocator::initialize(VkDevice inDevice) {
device = inDevice;
currentPool = createPool();
}
void ext::vulkan::DescriptorAllocator::destroy() {
if ( currentPool ) vkDestroyDescriptorPool(device, currentPool, nullptr);
for ( auto p : usedPools ) vkDestroyDescriptorPool(device, p, nullptr);
usedPools.clear();
}
VkDescriptorPool ext::vulkan::DescriptorAllocator::createPool() {
VkDescriptorPoolCreateInfo poolInfo = {};
poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
poolInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
poolInfo.maxSets = 1000;
poolInfo.poolSizeCount = (uint32_t) poolSizes.size();
poolInfo.pPoolSizes = poolSizes.data();
VkDescriptorPool pool;
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &poolInfo, nullptr, &pool));
return pool;
}
bool ext::vulkan::DescriptorAllocator::allocate( VkDescriptorSet* set, VkDescriptorSetLayout layout ) {
if ( currentPool == VK_NULL_HANDLE ) currentPool = createPool();
VkDescriptorSetAllocateInfo allocInfo = {};
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocInfo.descriptorPool = currentPool;
allocInfo.descriptorSetCount = 1;
allocInfo.pSetLayouts = &layout;
VkResult result = vkAllocateDescriptorSets(device, &allocInfo, set);
if ( result == VK_ERROR_OUT_OF_POOL_MEMORY || result == VK_ERROR_FRAGMENTED_POOL ) {
usedPools.push_back(currentPool);
currentPool = createPool();
allocInfo.descriptorPool = currentPool;
result = vkAllocateDescriptorSets(device, &allocInfo, set);
}
return result == VK_SUCCESS;
}
#endif

View File

@ -12,6 +12,8 @@
#include <fstream>
#include <regex>
#define USE_SHARED_PIPELINES 0
#define VK_DEBUG_VALIDATION_MESSAGE(...)\
// VK_VALIDATION_MESSAGE(x);
@ -19,6 +21,8 @@ namespace {
uint32_t VERTEX_BUFFER_BIND_ID = 0;
}
uf::stl::unordered_map<ext::vulkan::GraphicDescriptor, ext::vulkan::Pipeline> ext::vulkan::Pipeline::pipelines;
PFN_vkGetBufferDeviceAddressKHR ext::vulkan::vkGetBufferDeviceAddressKHR = NULL; // = reinterpret_cast<PFN_vkGetBufferDeviceAddressKHR>(vkGetDeviceProcAddr(device, "vkGetBufferDeviceAddressKHR"));
PFN_vkCmdBuildAccelerationStructuresKHR ext::vulkan::vkCmdBuildAccelerationStructuresKHR = NULL; // = reinterpret_cast<PFN_vkCmdBuildAccelerationStructuresKHR>(vkGetDeviceProcAddr(device, "vkCmdBuildAccelerationStructuresKHR"));
PFN_vkBuildAccelerationStructuresKHR ext::vulkan::vkBuildAccelerationStructuresKHR = NULL; // = reinterpret_cast<PFN_vkBuildAccelerationStructuresKHR>(vkGetDeviceProcAddr(device, "vkBuildAccelerationStructuresKHR"));
@ -36,12 +40,13 @@ void ext::vulkan::Pipeline::initialize( const Graphic& graphic ) {
return this->initialize( graphic, graphic.descriptor );
}
void ext::vulkan::Pipeline::initialize( const Graphic& graphic, const GraphicDescriptor& descriptor ) {
if ( pipeline != VK_NULL_HANDLE ) return;
this->device = graphic.device;
this->descriptor = descriptor;
this->metadata.type = descriptor.pipeline;
Device& device = *graphic.device;
auto shaders = getShaders( graphic.material.shaders, descriptor.pipeline );
auto shaders = graphic.material.getShaders( descriptor.pipeline );
assert( shaders.size() > 0 );
uint32_t subpass = descriptor.subpass;
@ -78,20 +83,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(),
@ -100,13 +91,6 @@ void ext::vulkan::Pipeline::initialize( const Graphic& graphic, const GraphicDes
VK_CHECK_RESULT(vkCreateDescriptorSetLayout( device, &descriptorLayout, nullptr, &descriptorSetLayout ));
VK_REGISTER_HANDLE( 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
@ -393,10 +377,7 @@ 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 = getShaders( graphic.material.shaders, descriptor.pipeline );
auto shaders = graphic.material.getShaders( descriptor.pipeline );
// create dynamic offset ranges
STATIC_THREAD_LOCAL(uf::stl::vector<uint32_t>, dynamicOffsets);
@ -440,6 +421,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() );
}
@ -455,13 +521,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;
@ -470,10 +533,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
@ -496,18 +559,18 @@ 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);
auto& renderTarget = renderMode.getRenderTarget(/*descriptor.renderTarget*/);
auto shaders = getShaders( graphic.material.shaders, descriptor.pipeline );
auto shaders = graphic.material.getShaders( descriptor.pipeline );
uf::stl::vector<VkWriteDescriptorSet> writeDescriptorSets;
uf::stl::vector<uf::renderer::AccelerationStructure> tlases;
@ -887,7 +950,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+)\]$/)");
@ -916,64 +979,21 @@ 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;
}
void ext::vulkan::DescriptorSet::destroy() {
// no-op
}
// 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;
}
*/
}
uf::stl::vector<ext::vulkan::Shader*> ext::vulkan::Pipeline::getShaders( uf::stl::vector<ext::vulkan::Shader>& shaders, const uf::stl::string& type ) {
uf::stl::unordered_map<uf::stl::string, ext::vulkan::Shader*> map;
uf::stl::vector<ext::vulkan::Shader*> res;
bool isCompute = false;
for ( auto& shader : shaders ) {
if ( shader.metadata.pipeline != "" && shader.metadata.pipeline != (type == "" ? metadata.type : type) ) continue;
if ( shader.descriptor.stage == VK_SHADER_STAGE_COMPUTE_BIT ) isCompute = true;
}
for ( auto& shader : shaders ) {
if ( shader.metadata.pipeline != "" && shader.metadata.pipeline != (type == "" ? metadata.type : type) ) continue;
if ( isCompute && shader.descriptor.stage != VK_SHADER_STAGE_COMPUTE_BIT ) continue;
map[shader.metadata.type] = &shader;
}
for ( auto pair : map ) res.insert( res.begin(), pair.second);
return res;
}
uf::stl::vector<const ext::vulkan::Shader*> ext::vulkan::Pipeline::getShaders( const uf::stl::vector<ext::vulkan::Shader>& shaders, const uf::stl::string& type ) const {
uf::stl::vector<const ext::vulkan::Shader*> ext::vulkan::Material::getShaders( const uf::stl::string& type ) const {
uf::stl::unordered_map<uf::stl::string, const ext::vulkan::Shader*> map;
uf::stl::vector<const ext::vulkan::Shader*> res;
bool isCompute = false;
for ( auto& shader : shaders ) {
if ( shader.metadata.pipeline != "" && shader.metadata.pipeline != (type == "" ? metadata.type : type) ) continue;
if ( shader.metadata.pipeline != "" && shader.metadata.pipeline != type ) continue;
if ( shader.descriptor.stage == VK_SHADER_STAGE_COMPUTE_BIT ) isCompute = true;
}
for ( auto& shader : shaders ) {
if ( shader.metadata.pipeline != "" && shader.metadata.pipeline != (type == "" ? metadata.type : type) ) continue;
if ( shader.metadata.pipeline != "" && shader.metadata.pipeline != type ) continue;
if ( isCompute && shader.descriptor.stage != VK_SHADER_STAGE_COMPUTE_BIT ) continue;
map[shader.metadata.type] = &shader;
}
@ -1041,6 +1061,8 @@ void ext::vulkan::Material::attachShader( const uf::stl::string& filename, VkSha
metadata.json["shaders"][pipeline][type]["index"] = shaders.size() - 1;
metadata.json["shaders"][pipeline][type]["filename"] = filename;
metadata.shaders[pipeline+":"+type] = shaders.size() - 1;
uf::hash( metadata.hashes[pipeline], filename );
}
void ext::vulkan::Material::initializeShaders( const uf::stl::vector<std::pair<uf::stl::string, VkShaderStageFlagBits>>& layout, const uf::stl::string& pipeline ) {
shaders.clear(); shaders.reserve( layout.size() );
@ -1081,26 +1103,34 @@ 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 descriptor
this->descriptor.material = material.metadata.hashes[descriptor.pipeline];
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 ) {
#if USE_SHARED_PIPELINES
auto& pipeline = Pipeline::pipelines[descriptor];
#else
auto& pipeline = pipelines[descriptor];
#endif
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
@ -1153,11 +1183,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;
@ -1815,7 +1840,11 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect
}
}
bool ext::vulkan::Graphic::hasPipeline( const GraphicDescriptor& descriptor ) const {
#if USE_SHARED_PIPELINES
return Pipeline::pipelines.count( descriptor ) > 0;
#else
return pipelines.count( descriptor ) > 0;
#endif
}
ext::vulkan::Pipeline& ext::vulkan::Graphic::getPipeline() {
return getPipeline( descriptor );
@ -1825,34 +1854,82 @@ const ext::vulkan::Pipeline& ext::vulkan::Graphic::getPipeline() const {
}
ext::vulkan::Pipeline& ext::vulkan::Graphic::getPipeline( const GraphicDescriptor& descriptor ) {
if ( !hasPipeline(descriptor) ) return initializePipeline( descriptor );
#if USE_SHARED_PIPELINES
return Pipeline::pipelines[descriptor];
#else
return pipelines[descriptor];
#endif
}
const ext::vulkan::Pipeline& ext::vulkan::Graphic::getPipeline( const GraphicDescriptor& descriptor ) const {
if ( !hasPipeline(descriptor) ) UF_EXCEPTION("does not have pipeline");
#if USE_SHARED_PIPELINES
return Pipeline::pipelines.at(descriptor);
#else
return pipelines.at(descriptor);
#endif
}
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& pipeline = getPipeline();
auto& descriptorSet = descriptorSets[descriptor];
// ensure pipeline exists (because we're passing this as const)
pipeline.initialize(*this, 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 );
}
void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer, const GraphicDescriptor& descriptor, size_t pass, size_t draw, size_t offset ) const {
if ( !process ) return;
if ( !this->hasPipeline( descriptor ) ) {
//UF_MSG_DEBUG("{} has no valid pipeline ({}:{}:{})", (void*) this, descriptor.renderMode, descriptor.renderTarget, descriptor.pipeline);
#if USE_SHARED_PIPELINES
if ( Pipeline::pipelines.count( descriptor ) == 0 ) {
Pipeline::pipelines[descriptor].initialize(*this, descriptor);
}
#endif
if ( !hasPipeline( descriptor ) ) {
// UF_MSG_DEBUG("{} has no valid pipeline ({}:{}:{})", (void*) this, descriptor.renderMode, descriptor.renderTarget, descriptor.pipeline);
return;
}
if ( !hasDescriptorSet( descriptor ) ) {
// UF_MSG_DEBUG("{} has no valid descriptor set ({}:{}:{})", (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);
return;
}
if ( !pipeline.metadata.process ) return;
pipeline.record(*this, descriptor, commandBuffer, pass, draw, offset);
auto& descriptorSet = this->getDescriptorSet( descriptor );
auto shaders = pipeline.getShaders( material.shaders, descriptor.pipeline );
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 ) {
if ( shader->descriptor.stage == VK_SHADER_STAGE_COMPUTE_BIT ) return;
if (
@ -1986,11 +2063,12 @@ 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();
// ext::vulkan::states::rebuild = true;
@ -2018,7 +2096,7 @@ void ext::vulkan::GraphicDescriptor::parse( ext::json::Value& metadata ) {
}
ext::vulkan::GraphicDescriptor::hash_t ext::vulkan::GraphicDescriptor::hash() const {
size_t seed{};
uf::hash( seed, aux, subpass, renderMode, renderTarget, pipeline, topology, cullMode, fill, lineWidth, frontFace, depth.test, depth.write, depth.operation, depth.bias.enable, depth.bias.constant, depth.bias.slope, depth.bias.clamp );
uf::hash( seed, aux, subpass, renderMode, renderTarget, material, pipeline, topology, cullMode, fill, lineWidth, frontFace, depth.test, depth.write, depth.operation, depth.bias.enable, depth.bias.constant, depth.bias.slope, depth.bias.clamp );
return seed;
}

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

@ -526,11 +526,7 @@ void ext::vulkan::DeferredRenderMode::build( bool resized ) {
{
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

@ -494,11 +494,14 @@ void ext::vulkan::initialize( bool soft ) {
}
void ext::vulkan::tick() {
// ext::vulkan::mutex.lock();
if ( ext::vulkan::states::resized || ext::vulkan::settings::experimental::rebuildOnTickBegin ) {
synchronize(0b11);
if ( ext::vulkan::states::resized ) {
// synchronize(0b11);
ext::vulkan::states::rebuild = true;
::skip = true;
}
if ( ext::vulkan::settings::experimental::rebuildOnTickBegin ) {
ext::vulkan::states::rebuild = true;
}
ext::fsr::tick();
@ -519,7 +522,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 +530,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]{

View File

@ -44,7 +44,7 @@ void uf::camera::update( pod::Camera& camera, bool override ) {
#if UF_USE_OPENVR
if ( this->m_pod.stereoscopic && ext::openvr::context ) {
camera.transform.orientation = uf::quaternion::identity();
pod::Matrix4t<> view = uf::matrix::inverse( uf::transform::model( camera.transform, false, 1 ) );
pod::Matrix4t<> view = uf::matrix::inverse( uf::transform::model( camera.transform ) );
camera.transform.orientation = ext::openvr::hmdQuaternion();
uf::camera::view( camera, ext::openvr::hmdViewMatrix(vr::Eye_Left, view ), 0 );
@ -52,7 +52,7 @@ void uf::camera::update( pod::Camera& camera, bool override ) {
} else
#endif
{
pod::Matrix4t<> view = uf::matrix::inverse( uf::transform::model( camera.transform, false, 1 ) );
pod::Matrix4t<> view = uf::matrix::inverse( uf::transform::model( camera.transform ) );
uf::camera::view( camera, view );
}
}

View File

@ -131,13 +131,14 @@ void uf::physics::step( pod::World& world, float dt ) {
if ( uf::physics::settings.warmupSolver ) impl::prepareManifoldCache( uf::physics::settings.manifoldsCache, islands, bodies );
// iterate islands
#pragma omp parallel for schedule(dynamic)
for ( auto& island : islands ) {
//#pragma omp parallel for schedule(dynamic)
auto tasks = uf::thread::schedule(true);
for ( auto& island : islands ) tasks.queue([&]{
STATIC_THREAD_LOCAL(uf::stl::vector<pod::Manifold>, manifolds);
manifolds.reserve(uf::physics::settings.reserveCount);
// sleeping island, skip (asleep islands shouldn't ever be in here)
if ( !island.awake ) continue;
if ( !island.awake ) return;
// iterate overlap pairs
for ( auto& [ ia, ib ] : island.pairs ) {
@ -197,7 +198,8 @@ void uf::physics::step( pod::World& world, float dt ) {
if ( uf::physics::settings.warmupSolver ) {
impl::updateManifoldCache( manifolds, uf::physics::settings.manifoldsCache );
}
}
});
uf::thread::execute( tasks );
if ( uf::physics::settings.warmupSolver ) impl::pruneManifoldCache( uf::physics::settings.manifoldsCache );