refractored descriptor sets to properly handle multiple sets for a given shader
This commit is contained in:
parent
e35806bb04
commit
f132f5d6d2
@ -110,7 +110,8 @@
|
||||
"invariant": {
|
||||
"default stage buffers": true,
|
||||
"default defer buffer destroy": true,
|
||||
"default command buffer immediate": true,
|
||||
"default command buffer immediate": false,
|
||||
"n-buffered uniform": false,
|
||||
"multithreaded recording": true
|
||||
},
|
||||
"pipelines": {
|
||||
@ -118,9 +119,9 @@
|
||||
"gui": true,
|
||||
"vsync": true, // vsync on vulkan side rather than engine-side
|
||||
"hdr": true,
|
||||
"vxgi": true, // to-do: fix issues
|
||||
"vxgi": false, // to-do: fix issues
|
||||
"culling": false,
|
||||
"bloom": false,
|
||||
"bloom": true,
|
||||
"dof": false,
|
||||
"rt": false,
|
||||
"fsr": false,
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
[ 0, 0, 0, 0 ]
|
||||
],
|
||||
"shader": {
|
||||
"mode": 0,
|
||||
"mode": 10,
|
||||
"scalar": 16,
|
||||
"parameters": [ 0, 0, 0, "time" ]
|
||||
}
|
||||
|
||||
@ -26,33 +26,33 @@ layout (constant_id = 1) const uint CUBEMAPS = 128;
|
||||
#endif
|
||||
|
||||
#if !MULTISAMPLING
|
||||
layout(binding = 0) uniform utexture2DArray samplerId;
|
||||
layout(binding = 0, set = 0) uniform utexture2DArray samplerId;
|
||||
#if BARYCENTRIC
|
||||
#if !BARYCENTRIC_CALCULATE
|
||||
layout(binding = 1) uniform texture2DArray samplerBary;
|
||||
layout(binding = 1, set = 0) uniform texture2DArray samplerBary;
|
||||
#endif
|
||||
#else
|
||||
layout(binding = 1) uniform texture2DArray samplerUv;
|
||||
layout(binding = 2) uniform texture2DArray samplerNormal;
|
||||
layout(binding = 1, set = 0) uniform texture2DArray samplerUv;
|
||||
layout(binding = 2, set = 0) uniform texture2DArray samplerNormal;
|
||||
#endif
|
||||
layout(binding = 3) uniform texture2DArray samplerDepth;
|
||||
layout(binding = 3, set = 0) uniform texture2DArray samplerDepth;
|
||||
#else
|
||||
layout(binding = 0) uniform utexture2DMSArray samplerId;
|
||||
layout(binding = 0, set = 0) uniform utexture2DMSArray samplerId;
|
||||
#if BARYCENTRIC
|
||||
#if !BARYCENTRIC_CALCULATE
|
||||
layout(binding = 1) uniform texture2DMSArray samplerBary;
|
||||
layout(binding = 1, set = 0) uniform texture2DMSArray samplerBary;
|
||||
#endif
|
||||
#else
|
||||
layout(binding = 1) uniform texture2DMSArray samplerUv;
|
||||
layout(binding = 2) uniform texture2DMSArray samplerNormal;
|
||||
layout(binding = 1, set = 0) uniform texture2DMSArray samplerUv;
|
||||
layout(binding = 2, set = 0) uniform texture2DMSArray samplerNormal;
|
||||
#endif
|
||||
layout(binding = 3) uniform texture2DMSArray samplerDepth;
|
||||
layout(binding = 3, set = 0) uniform texture2DMSArray samplerDepth;
|
||||
#endif
|
||||
|
||||
|
||||
layout(binding = 7, rgba16f) uniform writeonly image2DArray imageColor;
|
||||
layout(binding = 8, rgba16f) uniform writeonly image2DArray imageBright;
|
||||
layout(binding = 9, rg16f) uniform writeonly image2DArray imageMotion;
|
||||
layout(binding = 7, set = 0, rgba16f) uniform writeonly image2DArray imageColor;
|
||||
layout(binding = 8, set = 0, rgba16f) uniform writeonly image2DArray imageBright;
|
||||
layout(binding = 9, set = 0, rg16f) uniform writeonly image2DArray imageMotion;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
@ -61,46 +61,46 @@ layout( push_constant ) uniform PushBlock {
|
||||
|
||||
#include "../../../common/structs.h"
|
||||
|
||||
layout (binding = 10) uniform Camera {
|
||||
layout (binding = 10, set = 0) uniform Camera {
|
||||
Viewport viewport[2];
|
||||
} camera;
|
||||
|
||||
layout (binding = 11) uniform UBO {
|
||||
layout (binding = 11, set = 0) uniform UBO {
|
||||
EyeMatrices eyes[2];
|
||||
|
||||
Settings settings;
|
||||
} ubo;
|
||||
|
||||
layout (std140, binding = 12) readonly buffer DrawCommands {
|
||||
layout (std140, binding = 12, set = 0) readonly buffer DrawCommands {
|
||||
DrawCommand drawCommands[];
|
||||
};
|
||||
layout (std140, binding = 13) readonly buffer Instances {
|
||||
layout (std140, binding = 13, set = 0) readonly buffer Instances {
|
||||
Instance instances[];
|
||||
};
|
||||
layout (std140, binding = 14) readonly buffer InstanceAddresseses {
|
||||
layout (std140, binding = 14, set = 0) readonly buffer InstanceAddresseses {
|
||||
InstanceAddresses instanceAddresses[];
|
||||
};
|
||||
layout (std140, binding = 15) readonly buffer Objects {
|
||||
layout (std140, binding = 15, set = 0) readonly buffer Objects {
|
||||
Object objects[];
|
||||
};
|
||||
layout (std140, binding = 16) readonly buffer Materials {
|
||||
layout (std140, binding = 16, set = 0) readonly buffer Materials {
|
||||
Material materials[];
|
||||
};
|
||||
layout (std140, binding = 17) readonly buffer Textures {
|
||||
layout (std140, binding = 17, set = 0) readonly buffer Textures {
|
||||
Texture textures[];
|
||||
};
|
||||
layout (std140, binding = 18) readonly buffer Lights {
|
||||
layout (std140, binding = 18, set = 0) readonly buffer Lights {
|
||||
Light lights[];
|
||||
};
|
||||
|
||||
layout (binding = 19) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (binding = 20) uniform samplerCube samplerCubemaps[CUBEMAPS];
|
||||
layout (binding = 21) uniform sampler3D samplerNoise;
|
||||
layout (binding = 19, set = 1) uniform sampler2D samplerTextures[TEXTURES];
|
||||
layout (binding = 20, set = 1) uniform samplerCube samplerCubemaps[CUBEMAPS];
|
||||
layout (binding = 21, set = 0) uniform sampler3D samplerNoise;
|
||||
#if VXGI
|
||||
layout (binding = 22) uniform sampler3D voxelOutput[CASCADES];
|
||||
layout (binding = 22, set = 0) uniform sampler3D voxelOutput[CASCADES];
|
||||
#endif
|
||||
#if RT
|
||||
layout (binding = 23) uniform accelerationStructureEXT tlas;
|
||||
layout (binding = 23, set = 0) uniform accelerationStructureEXT tlas;
|
||||
#endif
|
||||
|
||||
#if BUFFER_REFERENCE
|
||||
@ -284,7 +284,7 @@ void directLighting() {
|
||||
if ( ubo.settings.mode.type == 0x000A ) {
|
||||
Ray ray;
|
||||
ray.direction = surface.ray.direction;
|
||||
ray.origin = surface.ray.origin;
|
||||
ray.origin = surface.position.world;
|
||||
ray.origin -= ray.direction;
|
||||
|
||||
vec4 radiance = voxelConeTrace( ray, 0 );
|
||||
|
||||
@ -20,7 +20,7 @@ namespace ext {
|
||||
|
||||
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
|
||||
VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE;
|
||||
uf::stl::vector<VkDescriptorSetLayout> descriptorSetLayouts;
|
||||
GraphicDescriptor descriptor = {};
|
||||
|
||||
uf::stl::vector<VkStridedDeviceAddressRegionKHR> sbtEntries;
|
||||
@ -31,12 +31,12 @@ namespace ext {
|
||||
void destroy();
|
||||
};
|
||||
|
||||
struct UF_API DescriptorSet : public Buffers {
|
||||
struct UF_API DescriptorSets : public Buffers {
|
||||
bool aliased = false;
|
||||
|
||||
Device* device = NULL;
|
||||
|
||||
VkDescriptorSet descriptorSet = {};
|
||||
uf::stl::vector<VkDescriptorSet> descriptorSets;
|
||||
GraphicDescriptor descriptor = {};
|
||||
|
||||
struct {
|
||||
@ -47,7 +47,7 @@ namespace ext {
|
||||
void initialize( const Graphic& graphic );
|
||||
void initialize( const Graphic& graphic, const GraphicDescriptor& descriptor );
|
||||
void update( const Graphic& graphic );
|
||||
void update( const Graphic& graphic, const GraphicDescriptor& descriptor );
|
||||
void update( const Graphic& graphic, const GraphicDescriptor& descriptor, const uf::stl::vector<Shader::Metadata::Definition>& = {} );
|
||||
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();
|
||||
@ -94,7 +94,7 @@ namespace ext {
|
||||
Material material = {};
|
||||
|
||||
uf::stl::unordered_map<GraphicDescriptor, Pipeline> pipelines;
|
||||
uf::stl::unordered_map<GraphicDescriptor, DescriptorSet> descriptorSets;
|
||||
uf::stl::unordered_map<GraphicDescriptor, DescriptorSets> descriptorSets;
|
||||
|
||||
struct {
|
||||
uf::stl::unordered_map<uf::stl::string, size_t> buffers;
|
||||
@ -129,12 +129,12 @@ namespace ext {
|
||||
const Pipeline& getPipeline( const GraphicDescriptor& descriptor ) const;
|
||||
|
||||
void initializeDescriptorSet();
|
||||
DescriptorSet& initializeDescriptorSet( const GraphicDescriptor& descriptor );
|
||||
DescriptorSets& 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;
|
||||
DescriptorSets& getDescriptorSet();
|
||||
const DescriptorSets& getDescriptorSet() const;
|
||||
DescriptorSets& getDescriptorSet( const GraphicDescriptor& descriptor );
|
||||
const DescriptorSets& 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;
|
||||
|
||||
@ -29,7 +29,7 @@ namespace ext {
|
||||
|
||||
VkShaderModule module = VK_NULL_HANDLE;
|
||||
VkPipelineShaderStageCreateInfo descriptor = {};
|
||||
uf::stl::vector<VkDescriptorSetLayoutBinding> descriptorSetLayoutBindings;
|
||||
uf::stl::map<size_t, uf::stl::vector<VkDescriptorSetLayoutBinding>> descriptorSetLayoutBindings;
|
||||
uf::stl::vector<VkSpecializationMapEntry> specializationMapEntries;
|
||||
VkSpecializationInfo specializationInfo = {};
|
||||
|
||||
@ -42,48 +42,23 @@ namespace ext {
|
||||
bool autoInitializeUniformUserdatas = false;
|
||||
|
||||
struct Definition {
|
||||
struct InOut {
|
||||
uf::stl::string name = "";
|
||||
uint32_t index = 0;
|
||||
uint32_t binding = 0;
|
||||
uint32_t size = 0;
|
||||
// int32_t buffer = -1;
|
||||
ext::vulkan::enums::Image::viewType_t type{};
|
||||
};
|
||||
struct Texture {
|
||||
uf::stl::string name = "";
|
||||
uint32_t index = 0;
|
||||
uint32_t binding = 0;
|
||||
uint32_t size = 0;
|
||||
ext::vulkan::enums::Image::viewType_t type{};
|
||||
};
|
||||
struct Uniform {
|
||||
uf::stl::string name = "";
|
||||
uint32_t index = 0;
|
||||
uint32_t binding = 0;
|
||||
uint32_t size = 0;
|
||||
// int32_t buffer = -1;
|
||||
};
|
||||
struct Storage {
|
||||
uf::stl::string name = "";
|
||||
uint32_t index = 0;
|
||||
uint32_t binding = 0;
|
||||
uint32_t size = 0;
|
||||
// int32_t buffer = -1;
|
||||
};
|
||||
struct AccelerationStructure {
|
||||
uf::stl::string name = "";
|
||||
uint32_t index = 0;
|
||||
uint32_t binding = 0;
|
||||
uint32_t size = 0;
|
||||
// int32_t buffer = -1;
|
||||
};
|
||||
struct PushConstant {
|
||||
uf::stl::string name = "";
|
||||
uint32_t index = 0;
|
||||
uint32_t binding = 0;
|
||||
uint32_t size = 0;
|
||||
};
|
||||
uf::stl::string name = "";
|
||||
uint32_t index = 0;
|
||||
uint32_t set = 0;
|
||||
uint32_t binding = 0;
|
||||
uint32_t size = 0;
|
||||
// int32_t buffer = -1;
|
||||
ext::vulkan::enums::Image::viewType_t type{};
|
||||
};
|
||||
struct Definitions {
|
||||
// unused?
|
||||
typedef Metadata::Definition InOut;
|
||||
typedef Metadata::Definition Texture;
|
||||
typedef Metadata::Definition Uniform;
|
||||
typedef Metadata::Definition Storage;
|
||||
typedef Metadata::Definition AccelerationStructure;
|
||||
typedef Metadata::Definition PushConstant;
|
||||
|
||||
struct SpecializationConstants {
|
||||
uf::stl::string name = "";
|
||||
uint32_t index = 0;
|
||||
@ -95,9 +70,10 @@ namespace ext {
|
||||
float f;
|
||||
} value;
|
||||
};
|
||||
uf::stl::unordered_map<size_t, Texture> textures;
|
||||
|
||||
uf::stl::unordered_map<uf::stl::string, InOut> inputs;
|
||||
uf::stl::unordered_map<uf::stl::string, InOut> outputs;
|
||||
uf::stl::unordered_map<uf::stl::string, Texture> textures;
|
||||
uf::stl::unordered_map<uf::stl::string, Uniform> uniforms;
|
||||
uf::stl::unordered_map<uf::stl::string, Storage> storage;
|
||||
uf::stl::unordered_map<uf::stl::string, AccelerationStructure> accelerationStructure;
|
||||
@ -179,6 +155,8 @@ namespace ext {
|
||||
void setSpecializationConstants( const uf::stl::unordered_map<uf::stl::string, uint32_t>& values );
|
||||
void setDescriptorCounts( const uf::stl::unordered_map<uf::stl::string, uint32_t>& values );
|
||||
|
||||
Metadata::Definition getDefinition( const uf::stl::string& );
|
||||
|
||||
/*
|
||||
uf::Serializer getUniformJson( const uf::stl::string& name, bool cache = true );
|
||||
bool updateUniform( const uf::stl::string& name, const ext::json::Value& payload );
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
#define VK_DEFAULT_STAGE_BUFFERS ext::vulkan::settings::defaultStageBuffers
|
||||
#define VK_DEFAULT_DEFER_BUFFER_DESTROY ext::vulkan::settings::defaultDeferBufferDestroy
|
||||
#define VK_DEFAULT_COMMAND_BUFFER_IMMEDIATE ext::vulkan::settings::defaultCommandBufferImmediate
|
||||
#define VK_UBO_USE_N_BUFFERS 1
|
||||
#define VK_UBO_USE_N_BUFFERS ext::vulkan::settings::nBufferedUbos
|
||||
#define VK_USE_MULTIVIEW 1
|
||||
|
||||
namespace ext {
|
||||
@ -31,6 +31,7 @@ namespace ext {
|
||||
extern UF_API bool defaultStageBuffers;
|
||||
extern UF_API bool defaultDeferBufferDestroy;
|
||||
extern UF_API bool defaultCommandBufferImmediate;
|
||||
extern UF_API bool nBufferedUbos;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -143,7 +143,7 @@
|
||||
#define UF_MSG(...) {}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
#define STATIC_THREAD_LOCAL(T, name) T name;
|
||||
#else
|
||||
#define STATIC_THREAD_LOCAL(T, name) static thread_local T name; name.clear();
|
||||
|
||||
@ -238,12 +238,13 @@ void UF_API uf::load( ext::json::Value& json ) {
|
||||
#if UF_USE_VULKAN
|
||||
uf::renderer::settings::defaultStageBuffers = configRenderInvariantJson["default stage buffers"].as( uf::renderer::settings::defaultStageBuffers );
|
||||
uf::renderer::settings::defaultDeferBufferDestroy = configRenderInvariantJson["default defer buffer destroy"].as( uf::renderer::settings::defaultDeferBufferDestroy );
|
||||
#if 1
|
||||
#if 0
|
||||
uf::renderer::settings::defaultCommandBufferImmediate = true;
|
||||
/*global*/::requestDeferredCommandBufferSubmit = !configRenderInvariantJson["default command buffer immediate"].as( uf::renderer::settings::defaultCommandBufferImmediate );
|
||||
#else
|
||||
uf::renderer::settings::defaultCommandBufferImmediate = configRenderInvariantJson["default command buffer immediate"].as( uf::renderer::settings::defaultCommandBufferImmediate );
|
||||
#endif
|
||||
uf::renderer::settings::nBufferedUbos = configRenderInvariantJson["n-buffered uniform"].as( uf::renderer::settings::nBufferedUbos );
|
||||
#endif
|
||||
#if 1
|
||||
uf::renderer::settings::experimental::dedicatedThread = false;
|
||||
|
||||
@ -1273,19 +1273,26 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, uf::renderer::Graphic
|
||||
for ( uint32_t i = 0; !shouldUpdate && i < previousTextures.size() && i < graphic.material.textures.size(); ++i ) {
|
||||
if ( previousTextures[i] != graphic.material.textures[i].image ) shouldUpdate = true;
|
||||
}
|
||||
/*
|
||||
if ( shouldUpdate ) {
|
||||
// graphic.updatePipelines();
|
||||
graphic.update();
|
||||
renderMode.rebuild = true;
|
||||
metadata.shader.invalidated = false;
|
||||
}
|
||||
*/
|
||||
|
||||
if ( !graphic.material.hasShader(shaderType, shaderPipeline) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !graphic.material.hasShader(shaderType, shaderPipeline) ) return;
|
||||
auto& shader = graphic.material.getShader(shaderType, shaderPipeline);
|
||||
|
||||
if ( shouldUpdate ) {
|
||||
auto samplerTexturesDefinition = shader.getDefinition("samplerTextures");
|
||||
auto samplerCubemapsDefinition = shader.getDefinition("samplerCubemaps");
|
||||
auto descriptor = graphic.descriptor;
|
||||
auto& descriptorSets = graphic.getDescriptorSet( descriptor );
|
||||
descriptorSets.update( graphic, descriptor, { samplerTexturesDefinition, samplerCubemapsDefinition } );
|
||||
}
|
||||
|
||||
if ( !shader.hasUniform("UBO") ) return;
|
||||
//UF_MSG_DEBUG( "{}: {} {} // {}", uf::string::toString( self ), shaderType, shaderPipeline, uf::string::toString( uf::scene::getCurrentScene() ) );
|
||||
|
||||
|
||||
@ -1961,7 +1961,7 @@ void uf::graph::reload( pod::Graph& graph, pod::Node& node ) {
|
||||
|
||||
// necessary for OpenGL because recorded descriptors have invalidated pointers
|
||||
// Vulkan doesn't care about the CPU-side mesh data
|
||||
#if 1 || UF_USE_OPENGL
|
||||
#if UF_USE_OPENGL
|
||||
uf::renderer::states::rebuild = true;
|
||||
#endif
|
||||
|
||||
|
||||
@ -129,13 +129,11 @@ void ext::vulkan::Buffer::initialize( const void* data, VkDeviceSize length, VkB
|
||||
|
||||
// assume all UBOs are dynamic
|
||||
auto totalLength = length;
|
||||
#if VK_UBO_USE_N_BUFFERS
|
||||
if ( usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ) {
|
||||
if ( VK_UBO_USE_N_BUFFERS && usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ) {
|
||||
this->count = ext::vulkan::swapchain.buffers;
|
||||
this->alignment = device->properties.limits.minUniformBufferOffsetAlignment;
|
||||
totalLength = ALIGNED_SIZE( length, this->alignment ) * this->count;
|
||||
}
|
||||
#endif
|
||||
VK_CHECK_RESULT(device->createBuffer( nullptr, totalLength, usage, memoryProperties, *this ));
|
||||
|
||||
if ( length != totalLength ) this->updateDescriptor( length, 0 );
|
||||
@ -181,11 +179,9 @@ bool ext::vulkan::Buffer::update( const void* data, VkDeviceSize length ) const
|
||||
region.size = length;
|
||||
region.srcOffset = 0;
|
||||
region.dstOffset = 0;
|
||||
#if VK_UBO_USE_N_BUFFERS
|
||||
if ( this->count == ext::vulkan::swapchain.buffers ) {
|
||||
if ( VK_UBO_USE_N_BUFFERS && this->count == ext::vulkan::swapchain.buffers ) {
|
||||
region.dstOffset = this->getOffset( states::currentBuffer );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( !VK_DEFAULT_STAGE_BUFFERS ) {
|
||||
|
||||
@ -60,28 +60,50 @@ void ext::vulkan::Pipeline::initialize( const Graphic& graphic, const GraphicDes
|
||||
uf::stl::vector<VkVertexInputBindingDescription> inputBindingDescriptions;
|
||||
uf::stl::vector<VkVertexInputAttributeDescription> attributeDescriptions;
|
||||
|
||||
uf::stl::map<uint32_t, uf::stl::vector<VkDescriptorSetLayoutBinding>> pipelineBindingsBySet;
|
||||
uf::stl::map<uint32_t, uf::stl::vector<VkDescriptorBindingFlags>> pipelineBindingFlagsBySet;
|
||||
|
||||
{
|
||||
uf::stl::vector<VkDescriptorBindingFlags> bindingFlags;
|
||||
|
||||
uint32_t maxSetIndex = 0;
|
||||
bool hasDynamicBuffer = false;
|
||||
|
||||
for ( auto* shader : shaders ) {
|
||||
for ( auto& binding : shader->descriptorSetLayoutBindings ) {
|
||||
switch ( binding.descriptorType ) {
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
||||
hasDynamicBuffer = true;
|
||||
break;
|
||||
for ( const auto& [setIndex, bindings] : shader->descriptorSetLayoutBindings ) {
|
||||
for ( auto& binding : bindings ) {
|
||||
switch ( binding.descriptorType ) {
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
||||
hasDynamicBuffer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto* shader : shaders ) {
|
||||
for ( auto& binding : shader->descriptorSetLayoutBindings ) {
|
||||
descriptorSetLayoutBindings.emplace_back( binding );
|
||||
auto& flags = bindingFlags.emplace_back();
|
||||
for ( const auto& [setIndex, bindings] : shader->descriptorSetLayoutBindings ) {
|
||||
maxSetIndex = MAX(maxSetIndex, setIndex);
|
||||
|
||||
flags |= VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT;
|
||||
if ( !hasDynamicBuffer ) flags |= VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT;
|
||||
auto& pipelineBindings = pipelineBindingsBySet[setIndex];
|
||||
auto& pipelineFlags = pipelineBindingFlagsBySet[setIndex];
|
||||
|
||||
for ( auto& binding : bindings ) {
|
||||
// Check if we already added this binding (e.g. Vertex and Fragment both use Set 0 Binding 0)
|
||||
auto it = std::find_if(pipelineBindings.begin(), pipelineBindings.end(),
|
||||
[&](const VkDescriptorSetLayoutBinding& b) { return b.binding == binding.binding; });
|
||||
|
||||
if ( it != pipelineBindings.end() ) {
|
||||
// Merge stage flags so the single layout knows it's used in both stages
|
||||
it->stageFlags |= binding.stageFlags;
|
||||
} else {
|
||||
// New binding
|
||||
pipelineBindings.emplace_back( binding );
|
||||
auto& flags = pipelineFlags.emplace_back();
|
||||
|
||||
flags |= VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT;
|
||||
if ( !hasDynamicBuffer ) flags |= VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t offset = 0;
|
||||
@ -101,26 +123,35 @@ void ext::vulkan::Pipeline::initialize( const Graphic& graphic, const GraphicDes
|
||||
}
|
||||
}
|
||||
|
||||
VkDescriptorSetLayoutBindingFlagsCreateInfo layoutBindingFlags = {};
|
||||
layoutBindingFlags.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO;
|
||||
layoutBindingFlags.bindingCount = bindingFlags.size();
|
||||
layoutBindingFlags.pBindingFlags = bindingFlags.data();
|
||||
descriptorSetLayouts.clear();
|
||||
descriptorSetLayouts.resize(maxSetIndex + 1, VK_NULL_HANDLE);
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo descriptorLayout = ext::vulkan::initializers::descriptorSetLayoutCreateInfo(
|
||||
descriptorSetLayoutBindings.data(),
|
||||
descriptorSetLayoutBindings.size()
|
||||
);
|
||||
for ( uint32_t set = 0; set <= maxSetIndex; ++set ) {
|
||||
auto& bindings = pipelineBindingsBySet[set];
|
||||
auto& bindingFlags = pipelineBindingFlagsBySet[set];
|
||||
|
||||
descriptorLayout.flags |= VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT;
|
||||
descriptorLayout.pNext = &layoutBindingFlags;
|
||||
VkDescriptorSetLayoutBindingFlagsCreateInfo layoutBindingFlags = {};
|
||||
layoutBindingFlags.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO;
|
||||
layoutBindingFlags.bindingCount = bindingFlags.size();
|
||||
layoutBindingFlags.pBindingFlags = bindingFlags.data();
|
||||
|
||||
VK_CHECK_RESULT(vkCreateDescriptorSetLayout( device, &descriptorLayout, nullptr, &descriptorSetLayout ));
|
||||
VK_REGISTER_HANDLE( descriptorSetLayout );
|
||||
VkDescriptorSetLayoutCreateInfo descriptorLayout = ext::vulkan::initializers::descriptorSetLayoutCreateInfo(
|
||||
bindings.data(),
|
||||
bindings.size()
|
||||
);
|
||||
|
||||
descriptorLayout.flags |= VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT;
|
||||
descriptorLayout.pNext = &layoutBindingFlags;
|
||||
|
||||
VK_CHECK_RESULT(vkCreateDescriptorSetLayout( device, &descriptorLayout, nullptr, &descriptorSetLayouts[set] ));
|
||||
VK_REGISTER_HANDLE( descriptorSetLayouts[set] );
|
||||
}
|
||||
|
||||
VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = ext::vulkan::initializers::pipelineLayoutCreateInfo(
|
||||
&descriptorSetLayout,
|
||||
1
|
||||
descriptorSetLayouts.data(),
|
||||
descriptorSetLayouts.size()
|
||||
);
|
||||
|
||||
pPipelineLayoutCreateInfo.pushConstantRangeCount = pushConstantRanges.size();
|
||||
pPipelineLayoutCreateInfo.pPushConstantRanges = pushConstantRanges.data();
|
||||
VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayout));
|
||||
@ -469,11 +500,13 @@ void ext::vulkan::Pipeline::destroy() {
|
||||
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;
|
||||
for ( auto descriptorSetLayout : descriptorSetLayouts ) {
|
||||
if ( descriptorSetLayout != VK_NULL_HANDLE ) {
|
||||
vkDestroyDescriptorSetLayout( *device, descriptorSetLayout, nullptr );
|
||||
VK_UNREGISTER_HANDLE( descriptorSetLayout );
|
||||
}
|
||||
}
|
||||
descriptorSetLayouts.clear();
|
||||
|
||||
// if ( settings::experimental::dedicatedThread ) ext::vulkan::states::rebuild = true;
|
||||
/*
|
||||
@ -484,22 +517,27 @@ void ext::vulkan::Pipeline::destroy() {
|
||||
*/
|
||||
}
|
||||
|
||||
void ext::vulkan::DescriptorSet::initialize( const Graphic& graphic ) {
|
||||
void ext::vulkan::DescriptorSets::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;
|
||||
void ext::vulkan::DescriptorSets::initialize( const Graphic& graphic, const GraphicDescriptor& descriptor ) {
|
||||
if ( !descriptorSets.empty() ) return;
|
||||
|
||||
this->device = graphic.device;
|
||||
this->descriptor = descriptor;
|
||||
|
||||
auto& pipeline = graphic.getPipeline( descriptor );
|
||||
UF_ASSERT(device->descriptorAllocator.allocate( &descriptorSet, pipeline.descriptorSetLayout ));
|
||||
descriptorSets.resize(pipeline.descriptorSetLayouts.size());
|
||||
|
||||
for( auto i = 0; i < pipeline.descriptorSetLayouts.size(); ++i ) {
|
||||
if ( pipeline.descriptorSetLayouts[i] == VK_NULL_HANDLE ) continue;
|
||||
UF_ASSERT(device->descriptorAllocator.allocate( &descriptorSets[i], pipeline.descriptorSetLayouts[i] ));
|
||||
}
|
||||
}
|
||||
void ext::vulkan::DescriptorSet::record( const Graphic& graphic, VkCommandBuffer commandBuffer, size_t pass, size_t draw, size_t offset ) const {
|
||||
void ext::vulkan::DescriptorSets::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 {
|
||||
void ext::vulkan::DescriptorSets::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 );
|
||||
|
||||
@ -530,9 +568,8 @@ void ext::vulkan::DescriptorSet::record( const Graphic& graphic, const GraphicDe
|
||||
else continue;
|
||||
}
|
||||
|
||||
#if VK_UBO_USE_N_BUFFERS
|
||||
dynamicOffsets.insert( dynamicOffsets.end(), shader->metadata.dynamicRanges.begin(), shader->metadata.dynamicRanges.end() );
|
||||
#endif
|
||||
if ( VK_UBO_USE_N_BUFFERS )
|
||||
dynamicOffsets.insert( dynamicOffsets.end(), shader->metadata.dynamicRanges.begin(), shader->metadata.dynamicRanges.end() );
|
||||
}
|
||||
|
||||
for ( auto& dynamicOffset : dynamicOffsets ) {
|
||||
@ -545,22 +582,22 @@ void ext::vulkan::DescriptorSet::record( const Graphic& graphic, const GraphicDe
|
||||
}
|
||||
|
||||
// Bind descriptor sets describing shader binding points
|
||||
vkCmdBindDescriptorSets(commandBuffer, (VkPipelineBindPoint) descriptor.bind.point, pipeline.pipelineLayout, 0, 1, &descriptorSet, dynamicOffsets.size(), dynamicOffsets.data());
|
||||
vkCmdBindDescriptorSets(commandBuffer, (VkPipelineBindPoint) descriptor.bind.point, pipeline.pipelineLayout, 0, descriptorSets.size(), descriptorSets.data(), dynamicOffsets.size(), dynamicOffsets.data());
|
||||
}
|
||||
void ext::vulkan::DescriptorSet::update( const Graphic& graphic ) {
|
||||
void ext::vulkan::DescriptorSets::update( const Graphic& graphic ) {
|
||||
return this->update( graphic, descriptor );
|
||||
}
|
||||
void ext::vulkan::DescriptorSet::update( const Graphic& graphic, const GraphicDescriptor& descriptor ) {
|
||||
void ext::vulkan::DescriptorSets::update( const Graphic& graphic, const GraphicDescriptor& descriptor, const uf::stl::vector<Shader::Metadata::Definition>& filter ) {
|
||||
//
|
||||
if ( descriptorSet == VK_NULL_HANDLE ) this->initialize( graphic, descriptor );
|
||||
if ( descriptorSets.empty() ) this->initialize( graphic, descriptor );
|
||||
this->descriptor = descriptor;
|
||||
|
||||
RenderMode& renderMode = ext::vulkan::getRenderMode(descriptor.renderMode, true);
|
||||
auto& renderTarget = renderMode.getRenderTarget(/*descriptor.renderTarget*/);
|
||||
|
||||
auto shaders = graphic.material.getShaders( descriptor.pipeline );
|
||||
uf::stl::vector<VkWriteDescriptorSet> writeDescriptorSets;
|
||||
uf::stl::vector<uf::renderer::AccelerationStructure> tlases;
|
||||
|
||||
STATIC_THREAD_LOCAL(uf::stl::vector<VkWriteDescriptorSet>, writeDescriptorSets);
|
||||
|
||||
struct Infos {
|
||||
uf::stl::vector<VkDescriptorBufferInfo> uniform;
|
||||
@ -577,12 +614,15 @@ void ext::vulkan::DescriptorSet::update( const Graphic& graphic, const GraphicDe
|
||||
|
||||
uf::stl::vector<VkDescriptorImageInfo> sampler;
|
||||
uf::stl::vector<VkDescriptorImageInfo> input;
|
||||
|
||||
uf::stl::vector<uf::renderer::AccelerationStructure> tlases;
|
||||
uf::stl::vector<ext::vulkan::enums::Image::viewType_t> texture_types;
|
||||
};
|
||||
uf::stl::vector<Infos> INFOS; INFOS.reserve( shaders.size() );
|
||||
STATIC_THREAD_LOCAL(uf::stl::vector<Infos>, INFOS);
|
||||
INFOS.reserve( shaders.size() );
|
||||
|
||||
for ( auto* shader : shaders ) {
|
||||
auto& infos = INFOS.emplace_back();
|
||||
uf::stl::vector<ext::vulkan::enums::Image::viewType_t> types;
|
||||
|
||||
this->collectBuffers( *shader, renderMode, graphic, [&]( const Buffer& buffer ){
|
||||
if ( buffer.usage & uf::renderer::enums::Buffer::UNIFORM ) infos.uniform.emplace_back(buffer.descriptor);
|
||||
@ -665,17 +705,22 @@ void ext::vulkan::DescriptorSet::update( const Graphic& graphic, const GraphicDe
|
||||
|
||||
// check if we can even consume that many infos
|
||||
size_t consumes = 0;
|
||||
for ( auto& layout : shader->descriptorSetLayoutBindings ) {
|
||||
switch ( layout.descriptorType ) {
|
||||
// consume an texture image info
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
|
||||
consumes += layout.descriptorCount;
|
||||
ext::vulkan::enums::Image::viewType_t imageType = shader->metadata.definitions.textures.at(layout.binding).type;
|
||||
types.reserve(consumes);
|
||||
for ( size_t i = 0; i < layout.descriptorCount; ++i ) types.emplace_back(imageType);
|
||||
} break;
|
||||
for ( const auto& [setIndex, bindings] : shader->descriptorSetLayoutBindings ) {
|
||||
for ( auto& layout : bindings ) {
|
||||
switch ( layout.descriptorType ) {
|
||||
// consume an texture image info
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
|
||||
consumes += layout.descriptorCount;
|
||||
for ( auto& [ _, def ] : shader->metadata.definitions.textures ) {
|
||||
if ( def.set != setIndex || def.binding != layout.binding ) continue;
|
||||
infos.texture_types.reserve(consumes);
|
||||
for ( size_t i = 0; i < layout.descriptorCount; ++i ) infos.texture_types.emplace_back(def.type);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -684,7 +729,7 @@ void ext::vulkan::DescriptorSet::update( const Graphic& graphic, const GraphicDe
|
||||
size_t maxTextures3D = 0;
|
||||
size_t maxTexturesCube = 0;
|
||||
size_t maxTexturesUnknown = 0;
|
||||
for ( auto& type : types ) {
|
||||
for ( auto& type : infos.texture_types ) {
|
||||
if ( type == ext::vulkan::enums::Image::VIEW_TYPE_3D ) ++maxTextures3D;
|
||||
else if ( type == ext::vulkan::enums::Image::VIEW_TYPE_CUBE ) ++maxTexturesCube;
|
||||
else if ( type == ext::vulkan::enums::Image::VIEW_TYPE_2D ) ++maxTextures2D;
|
||||
@ -699,7 +744,7 @@ void ext::vulkan::DescriptorSet::update( const Graphic& graphic, const GraphicDe
|
||||
while ( infos.imageUnknown.size() < maxTexturesUnknown ) infos.imageUnknown.emplace_back(Texture2D::empty.descriptor);
|
||||
|
||||
for ( size_t i = infos.image.size(); i < consumes; ++i ) {
|
||||
ext::vulkan::enums::Image::viewType_t type = i < types.size() ? types[i] : ext::vulkan::enums::Image::viewType_t{};
|
||||
ext::vulkan::enums::Image::viewType_t type = i < infos.texture_types.size() ? infos.texture_types[i] : ext::vulkan::enums::Image::viewType_t{};
|
||||
if ( type == ext::vulkan::enums::Image::VIEW_TYPE_3D ) infos.image.emplace_back(Texture3D::empty.descriptor);
|
||||
else if ( type == ext::vulkan::enums::Image::VIEW_TYPE_CUBE ) infos.image.emplace_back(TextureCube::empty.descriptor);
|
||||
else if ( type == ext::vulkan::enums::Image::VIEW_TYPE_2D ) infos.image.emplace_back(Texture2D::empty.descriptor);
|
||||
@ -708,18 +753,18 @@ void ext::vulkan::DescriptorSet::update( const Graphic& graphic, const GraphicDe
|
||||
|
||||
if ( !graphic.accelerationStructures.tops.empty() ) {
|
||||
auto tlas = graphic.accelerationStructures.tops.front();
|
||||
if ( tlas.handle != VK_NULL_HANDLE ) tlases.emplace_back(tlas);
|
||||
if ( tlas.handle != VK_NULL_HANDLE ) infos.tlases.emplace_back(tlas);
|
||||
}
|
||||
|
||||
if ( infos.accelerationStructure.empty() ) {
|
||||
uf::stl::string renderModeName = uf::renderer::hasRenderMode("Compute:RT", true) ? "Compute:RT" : "";
|
||||
auto& blitter = uf::renderer::getRenderMode(renderModeName, true).getBlitter();
|
||||
if ( !blitter.accelerationStructures.tops.empty() ) {
|
||||
tlases.emplace_back(blitter.accelerationStructures.tops.front());
|
||||
infos.tlases.emplace_back(blitter.accelerationStructures.tops.front());
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto& tlas : tlases ) {
|
||||
for ( auto& tlas : infos.tlases ) {
|
||||
infos.accelerationStructure.emplace_back(tlas.buffer.descriptor);
|
||||
|
||||
auto& descriptorAccelerationStructureInfo = infos.accelerationStructureInfos.emplace_back();
|
||||
@ -743,125 +788,142 @@ void ext::vulkan::DescriptorSet::update( const Graphic& graphic, const GraphicDe
|
||||
auto samplerInfo = infos.sampler.begin();
|
||||
auto inputInfo = infos.input.begin();
|
||||
|
||||
for ( auto& layout : shader->descriptorSetLayoutBindings ) {
|
||||
switch ( layout.descriptorType ) {
|
||||
// consume an texture image info
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
|
||||
ext::vulkan::enums::Image::viewType_t imageType = shader->metadata.definitions.textures.at(layout.binding).type;
|
||||
if ( imageType == ext::vulkan::enums::Image::VIEW_TYPE_2D ) {
|
||||
UF_ASSERT_BREAK_MSG( image2DInfo != infos.image2D.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*image2DInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
image2DInfo += layout.descriptorCount;
|
||||
} else if ( imageType == ext::vulkan::enums::Image::VIEW_TYPE_2D_ARRAY ) {
|
||||
UF_ASSERT_BREAK_MSG( image2DAInfo != infos.image2DA.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*image2DAInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
image2DAInfo += layout.descriptorCount;
|
||||
} else if ( imageType == ext::vulkan::enums::Image::VIEW_TYPE_CUBE ) {
|
||||
UF_ASSERT_BREAK_MSG( imageCubeInfo != infos.imageCube.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*imageCubeInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
imageCubeInfo += layout.descriptorCount;
|
||||
} else if ( imageType == ext::vulkan::enums::Image::VIEW_TYPE_3D ) {
|
||||
UF_ASSERT_BREAK_MSG( image3DInfo != infos.image3D.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*image3DInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
image3DInfo += layout.descriptorCount;
|
||||
} else {
|
||||
UF_ASSERT_BREAK_MSG( imageUnknownInfo != infos.imageUnknown.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*imageUnknownInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
imageUnknownInfo += layout.descriptorCount;
|
||||
}
|
||||
} break;
|
||||
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
|
||||
UF_ASSERT_BREAK_MSG( inputInfo != infos.input.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*inputInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
inputInfo += layout.descriptorCount;
|
||||
} break;
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER: {
|
||||
UF_ASSERT_BREAK_MSG( samplerInfo != infos.sampler.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*samplerInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
samplerInfo += layout.descriptorCount;
|
||||
} break;
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: {
|
||||
UF_ASSERT_BREAK_MSG( uniformBufferInfo != infos.uniform.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*uniformBufferInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
uniformBufferInfo += layout.descriptorCount;
|
||||
} break;
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
|
||||
UF_ASSERT_BREAK_MSG( storageBufferInfo != infos.storage.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*storageBufferInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
storageBufferInfo += layout.descriptorCount;
|
||||
} break;
|
||||
case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {
|
||||
UF_ASSERT_BREAK_MSG( accelerationStructureInfo != infos.accelerationStructure.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
auto& writeDescriptorSet = writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*accelerationStructureInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
writeDescriptorSet.pNext = &(*accelerationStructureInfos);
|
||||
for ( const auto& [setIndex, bindings] : shader->descriptorSetLayoutBindings ) {
|
||||
VkDescriptorSet descriptorSet = descriptorSets[setIndex];
|
||||
UF_ASSERT( descriptorSet != VK_NULL_HANDLE );
|
||||
|
||||
accelerationStructureInfo += layout.descriptorCount;
|
||||
accelerationStructureInfos += layout.descriptorCount;
|
||||
} break;
|
||||
for ( auto& layout : bindings ) {
|
||||
bool shouldWrite = filter.empty() || filter.end() != std::find_if( filter.begin(), filter.end(), [&]( auto d ) {
|
||||
return d.set == setIndex && d.binding == layout.binding;
|
||||
});
|
||||
|
||||
switch ( layout.descriptorType ) {
|
||||
// consume an texture image info
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
|
||||
ext::vulkan::enums::Image::viewType_t imageType = {};
|
||||
for ( auto& [ _, def ] : shader->metadata.definitions.textures ) {
|
||||
if ( def.set != setIndex || def.binding != layout.binding ) continue;
|
||||
imageType = def.type;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( imageType == ext::vulkan::enums::Image::VIEW_TYPE_2D ) {
|
||||
UF_ASSERT_BREAK_MSG( image2DInfo != infos.image2D.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
if ( shouldWrite ) writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*image2DInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
image2DInfo += layout.descriptorCount;
|
||||
} else if ( imageType == ext::vulkan::enums::Image::VIEW_TYPE_2D_ARRAY ) {
|
||||
UF_ASSERT_BREAK_MSG( image2DAInfo != infos.image2DA.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
if ( shouldWrite ) writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*image2DAInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
image2DAInfo += layout.descriptorCount;
|
||||
} else if ( imageType == ext::vulkan::enums::Image::VIEW_TYPE_CUBE ) {
|
||||
UF_ASSERT_BREAK_MSG( imageCubeInfo != infos.imageCube.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
if ( shouldWrite ) writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*imageCubeInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
imageCubeInfo += layout.descriptorCount;
|
||||
} else if ( imageType == ext::vulkan::enums::Image::VIEW_TYPE_3D ) {
|
||||
UF_ASSERT_BREAK_MSG( image3DInfo != infos.image3D.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
if ( shouldWrite ) writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*image3DInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
image3DInfo += layout.descriptorCount;
|
||||
} else {
|
||||
UF_ASSERT_BREAK_MSG( imageUnknownInfo != infos.imageUnknown.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
if ( shouldWrite ) writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*imageUnknownInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
imageUnknownInfo += layout.descriptorCount;
|
||||
}
|
||||
} break;
|
||||
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
|
||||
UF_ASSERT_BREAK_MSG( inputInfo != infos.input.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
if ( shouldWrite ) writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*inputInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
inputInfo += layout.descriptorCount;
|
||||
} break;
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER: {
|
||||
UF_ASSERT_BREAK_MSG( samplerInfo != infos.sampler.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
if ( shouldWrite ) writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*samplerInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
samplerInfo += layout.descriptorCount;
|
||||
} break;
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: {
|
||||
UF_ASSERT_BREAK_MSG( uniformBufferInfo != infos.uniform.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
if ( shouldWrite ) writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*uniformBufferInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
uniformBufferInfo += layout.descriptorCount;
|
||||
} break;
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
|
||||
UF_ASSERT_BREAK_MSG( storageBufferInfo != infos.storage.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
if ( shouldWrite ) writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*storageBufferInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
storageBufferInfo += layout.descriptorCount;
|
||||
} break;
|
||||
case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {
|
||||
UF_ASSERT_BREAK_MSG( accelerationStructureInfo != infos.accelerationStructure.end(), "Filename: {}\tCount: {}", shader->filename, layout.descriptorCount )
|
||||
if ( shouldWrite ) {
|
||||
auto& writeDescriptorSet = writeDescriptorSets.emplace_back(ext::vulkan::initializers::writeDescriptorSet(
|
||||
descriptorSet,
|
||||
layout.descriptorType,
|
||||
layout.binding,
|
||||
&(*accelerationStructureInfo),
|
||||
layout.descriptorCount
|
||||
));
|
||||
writeDescriptorSet.pNext = &(*accelerationStructureInfos);
|
||||
}
|
||||
|
||||
accelerationStructureInfo += layout.descriptorCount;
|
||||
accelerationStructureInfos += layout.descriptorCount;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -883,12 +945,16 @@ void ext::vulkan::DescriptorSet::update( const Graphic& graphic, const GraphicDe
|
||||
) {
|
||||
if ( descriptor.pImageInfo[i].imageView == VK_NULL_HANDLE || descriptor.pImageInfo[i].imageLayout == VK_IMAGE_LAYOUT_UNDEFINED ) {
|
||||
VK_DEBUG_VALIDATION_MESSAGE("Null image view or layout is undefined, replacing with fallback texture...");
|
||||
#if 0
|
||||
auto pointer = const_cast<VkDescriptorImageInfo*>(&descriptor.pImageInfo[i]);
|
||||
ext::vulkan::enums::Image::viewType_t imageType{};
|
||||
for ( auto* shader : shaders ) {
|
||||
if ( shader->metadata.definitions.textures.count(descriptor.dstBinding) == 0 ) continue;
|
||||
imageType = shader->metadata.definitions.textures.at(descriptor.dstBinding).type;
|
||||
break;
|
||||
for ( auto& [ _, def ] : shader->metadata.definitions.textures ) {
|
||||
// to-do: fix
|
||||
if ( def.set != descriptor.dstSet || def.binding != descriptor.dstBinding ) continue;
|
||||
imageType = def.type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( imageType == ext::vulkan::enums::Image::VIEW_TYPE_3D ) {
|
||||
*pointer = Texture3D::empty.descriptor;
|
||||
@ -897,6 +963,7 @@ void ext::vulkan::DescriptorSet::update( const Graphic& graphic, const GraphicDe
|
||||
} else {
|
||||
*pointer = Texture2D::empty.descriptor;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if 0
|
||||
if ( descriptor.pImageInfo[i].layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ) {
|
||||
@ -938,7 +1005,7 @@ PIPELINE_UPDATE_INVALID:
|
||||
});
|
||||
return;
|
||||
}
|
||||
void ext::vulkan::DescriptorSet::collectBuffers( const Shader& shader, const RenderMode& renderMode, const Graphic& graphic, const std::function<void(const Buffer&)>& lambda ) const {
|
||||
void ext::vulkan::DescriptorSets::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+)\]$/)");
|
||||
@ -968,7 +1035,7 @@ void ext::vulkan::DescriptorSet::collectBuffers( const Shader& shader, const Ren
|
||||
for ( auto& buffer : graphic.buffers ) lambda( buffer );
|
||||
}
|
||||
|
||||
void ext::vulkan::DescriptorSet::destroy() {
|
||||
void ext::vulkan::DescriptorSets::destroy() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@ -1020,11 +1087,13 @@ void ext::vulkan::Material::attachShader( const uf::stl::string& filename, VkSha
|
||||
}
|
||||
|
||||
// check how many samplers requested
|
||||
/*
|
||||
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
|
||||
if ( layout.descriptorType != VK_DESCRIPTOR_TYPE_SAMPLER ) continue;
|
||||
Sampler& sampler = samplers.emplace_back();
|
||||
sampler.initialize( *device );
|
||||
}
|
||||
*/
|
||||
|
||||
uf::stl::string type = "unknown";
|
||||
switch ( stage ) {
|
||||
@ -1871,7 +1940,7 @@ bool ext::vulkan::Graphic::hasDescriptorSet( const GraphicDescriptor& descriptor
|
||||
void ext::vulkan::Graphic::initializeDescriptorSet() {
|
||||
initializeDescriptorSet( this->descriptor );
|
||||
}
|
||||
ext::vulkan::DescriptorSet& ext::vulkan::Graphic::initializeDescriptorSet( const GraphicDescriptor& descriptor ) {
|
||||
ext::vulkan::DescriptorSets& ext::vulkan::Graphic::initializeDescriptorSet( const GraphicDescriptor& descriptor ) {
|
||||
auto& pipeline = getPipeline();
|
||||
auto& descriptorSet = descriptorSets[descriptor];
|
||||
|
||||
@ -1884,17 +1953,17 @@ ext::vulkan::DescriptorSet& ext::vulkan::Graphic::initializeDescriptorSet( const
|
||||
return descriptorSet;
|
||||
}
|
||||
|
||||
ext::vulkan::DescriptorSet& ext::vulkan::Graphic::getDescriptorSet() {
|
||||
ext::vulkan::DescriptorSets& ext::vulkan::Graphic::getDescriptorSet() {
|
||||
return getDescriptorSet( descriptor );
|
||||
}
|
||||
const ext::vulkan::DescriptorSet& ext::vulkan::Graphic::getDescriptorSet() const {
|
||||
const ext::vulkan::DescriptorSets& ext::vulkan::Graphic::getDescriptorSet() const {
|
||||
return getDescriptorSet( descriptor );
|
||||
}
|
||||
ext::vulkan::DescriptorSet& ext::vulkan::Graphic::getDescriptorSet( const GraphicDescriptor& descriptor ) {
|
||||
ext::vulkan::DescriptorSets& 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 {
|
||||
const ext::vulkan::DescriptorSets& ext::vulkan::Graphic::getDescriptorSet( const GraphicDescriptor& descriptor ) const {
|
||||
if ( !hasDescriptorSet(descriptor) ) UF_EXCEPTION("does not have descriptor set");
|
||||
return descriptorSets.at(descriptor);
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
#define VK_DEBUG_VALIDATION_MESSAGE(...)\
|
||||
//VK_VALIDATION_MESSAGE(__VA_ARGS__);
|
||||
|
||||
#define IS_DYNAMIC(name) name == "UBO_d"
|
||||
#define IS_DYNAMIC(name) true // name == "UBO"
|
||||
|
||||
#define UF_SHADER_PARSE_AS_JSON 0
|
||||
#if UF_SHADER_PARSE_AS_JSON
|
||||
@ -447,7 +447,9 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const uf::stl
|
||||
auto parseResource = [&]( const spirv_cross::Resource& resource, VkDescriptorType descriptorType, size_t index ) {
|
||||
const auto& type = comp.get_type(resource.type_id);
|
||||
const auto& base_type = comp.get_type(resource.base_type_id);
|
||||
const size_t binding = comp.get_decoration(resource.id, spv::DecorationBinding);
|
||||
const auto set = comp.get_decoration(resource.id, spv::DecorationDescriptorSet);
|
||||
const auto binding = comp.get_decoration(resource.id, spv::DecorationBinding);
|
||||
|
||||
const uf::stl::string name = resource.name;
|
||||
size_t arraySize = 1;
|
||||
if ( !type.array.empty() ) {
|
||||
@ -473,17 +475,19 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const uf::stl
|
||||
#if UF_SHADER_PARSE_AS_JSON
|
||||
metadata.json["definitions"]["textures"][key]["name"] = name;
|
||||
metadata.json["definitions"]["textures"][key]["index"] = index;
|
||||
metadata.json["definitions"]["textures"][key]["set"] = set;
|
||||
metadata.json["definitions"]["textures"][key]["binding"] = binding;
|
||||
metadata.json["definitions"]["textures"][key]["size"] = arraySize;
|
||||
metadata.json["definitions"]["textures"][key]["type"] = tname;
|
||||
#endif
|
||||
|
||||
metadata.definitions.textures[binding] = Shader::Metadata::Definition::Texture{
|
||||
name,
|
||||
index,
|
||||
binding,
|
||||
arraySize,
|
||||
etype,
|
||||
metadata.definitions.textures[name] = Shader::Metadata::Definition/*::Texture*/{
|
||||
.name = name,
|
||||
.index = index,
|
||||
.set = set,
|
||||
.binding = binding,
|
||||
.size = arraySize,
|
||||
.type = etype,
|
||||
};
|
||||
} break;
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
@ -507,17 +511,19 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const uf::stl
|
||||
{
|
||||
metadata.json["definitions"]["uniforms"][name]["name"] = name;
|
||||
metadata.json["definitions"]["uniforms"][name]["index"] = index;
|
||||
metadata.json["definitions"]["uniforms"][name]["set"] = set;
|
||||
metadata.json["definitions"]["uniforms"][name]["binding"] = binding;
|
||||
metadata.json["definitions"]["uniforms"][name]["size"] = bufferSize;
|
||||
metadata.json["definitions"]["uniforms"][name]["members"] = parseMembers(resource.type_id);
|
||||
}
|
||||
#endif
|
||||
// generate definition to unordered_map
|
||||
metadata.definitions.uniforms[name] = Shader::Metadata::Definition::Uniform{
|
||||
name,
|
||||
index,
|
||||
binding,
|
||||
bufferSize,
|
||||
metadata.definitions.uniforms[name] = Shader::Metadata::Definition/*::Uniform*/{
|
||||
.name = name,
|
||||
.index = index,
|
||||
.set = set,
|
||||
.binding = binding,
|
||||
.size = bufferSize,
|
||||
};
|
||||
|
||||
if ( descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ) {
|
||||
@ -534,15 +540,17 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const uf::stl
|
||||
{
|
||||
metadata.json["definitions"]["storage"][name]["name"] = name;
|
||||
metadata.json["definitions"]["storage"][name]["index"] = index;
|
||||
metadata.json["definitions"]["storage"][name]["set"] = set;
|
||||
metadata.json["definitions"]["storage"][name]["binding"] = binding;
|
||||
// metadata.json["definitions"]["storage"][name]["size"] = bufferSize;
|
||||
metadata.json["definitions"]["storage"][name]["members"] = parseMembers(resource.type_id);
|
||||
}
|
||||
#endif
|
||||
metadata.definitions.storage[name] = Shader::Metadata::Definition::Storage{
|
||||
name,
|
||||
index,
|
||||
binding
|
||||
metadata.definitions.storage[name] = Shader::Metadata::Definition/*::Storage*/{
|
||||
.name = name,
|
||||
.index = index,
|
||||
.set = set,
|
||||
.binding = binding
|
||||
};
|
||||
} break;
|
||||
case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {
|
||||
@ -551,18 +559,20 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const uf::stl
|
||||
{
|
||||
metadata.json["definitions"]["accelerationStructure"][name]["name"] = name;
|
||||
metadata.json["definitions"]["accelerationStructure"][name]["index"] = index;
|
||||
metadata.json["definitions"]["accelerationStructure"][name]["set"] = set;
|
||||
metadata.json["definitions"]["accelerationStructure"][name]["binding"] = binding;
|
||||
metadata.json["definitions"]["accelerationStructure"][name]["members"] = parseMembers(resource.type_id);
|
||||
}
|
||||
#endif
|
||||
metadata.definitions.accelerationStructure[name] = Shader::Metadata::Definition::AccelerationStructure{
|
||||
name,
|
||||
index,
|
||||
binding
|
||||
metadata.definitions.accelerationStructure[name] = Shader::Metadata::Definition/*::AccelerationStructure*/{
|
||||
.name = name,
|
||||
.index = index,
|
||||
.set = set,
|
||||
.binding = binding
|
||||
};
|
||||
} break;
|
||||
}
|
||||
descriptorSetLayoutBindings.push_back( ext::vulkan::initializers::descriptorSetLayoutBinding( descriptorType, stage, binding, arraySize ) );
|
||||
descriptorSetLayoutBindings[set].push_back( ext::vulkan::initializers::descriptorSetLayoutBinding( descriptorType, stage, binding, arraySize ) );
|
||||
};
|
||||
|
||||
//for ( const auto& resource : res.key ) {
|
||||
@ -577,11 +587,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const uf::stl
|
||||
LOOP_RESOURCES( storage_images, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE );
|
||||
LOOP_RESOURCES( separate_samplers, VK_DESCRIPTOR_TYPE_SAMPLER );
|
||||
LOOP_RESOURCES( subpass_inputs, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT );
|
||||
#if VK_UBO_USE_N_BUFFERS
|
||||
LOOP_RESOURCES( uniform_buffers, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC );
|
||||
#else
|
||||
LOOP_RESOURCES( uniform_buffers, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER );
|
||||
#endif
|
||||
LOOP_RESOURCES( uniform_buffers, VK_UBO_USE_N_BUFFERS ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER );
|
||||
LOOP_RESOURCES( storage_buffers, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER );
|
||||
LOOP_RESOURCES( acceleration_structures, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR );
|
||||
#undef LOOP_RESOURCES
|
||||
@ -628,7 +634,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const uf::stl
|
||||
#endif
|
||||
// generate definition to unordered_map
|
||||
{
|
||||
metadata.definitions.inputs[name] = Shader::Metadata::Definition::InOut{
|
||||
metadata.definitions.inputs[name] = Shader::Metadata::Definition/*::InOut*/{
|
||||
name,
|
||||
i,
|
||||
binding,
|
||||
@ -655,7 +661,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const uf::stl
|
||||
#endif
|
||||
// generate definition to unordered_map
|
||||
{
|
||||
metadata.definitions.outputs[name] = Shader::Metadata::Definition::InOut{
|
||||
metadata.definitions.outputs[name] = Shader::Metadata::Definition/*::InOut*/{
|
||||
name,
|
||||
i,
|
||||
binding,
|
||||
@ -699,7 +705,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const uf::stl
|
||||
#endif
|
||||
// generate definition to unordered_map
|
||||
{
|
||||
metadata.definitions.pushConstants[name] = Shader::Metadata::Definition::PushConstant{
|
||||
metadata.definitions.pushConstants[name] = Shader::Metadata::Definition/*::PushConstant*/{
|
||||
name,
|
||||
pushConstants.size() - 1,
|
||||
binding,
|
||||
@ -834,9 +840,11 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const uf::stl
|
||||
}
|
||||
|
||||
// organize layouts
|
||||
std::sort( descriptorSetLayoutBindings.begin(), descriptorSetLayoutBindings.end(), [&]( const VkDescriptorSetLayoutBinding& l, const VkDescriptorSetLayoutBinding& r ){
|
||||
return l.binding < r.binding;
|
||||
} );
|
||||
for ( auto& [setIndex, bindings] : descriptorSetLayoutBindings ) {
|
||||
std::sort( bindings.begin(), bindings.end(), [&]( const VkDescriptorSetLayoutBinding& l, const VkDescriptorSetLayoutBinding& r ){
|
||||
return l.binding < r.binding;
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
void ext::vulkan::Shader::destroy() {
|
||||
@ -982,16 +990,32 @@ void ext::vulkan::Shader::setSpecializationConstants( const uf::stl::unordered_m
|
||||
}
|
||||
}
|
||||
void ext::vulkan::Shader::setDescriptorCounts( const uf::stl::unordered_map<uf::stl::string, uint32_t>& values ) {
|
||||
for ( auto pair : this->metadata.definitions.textures ) {
|
||||
auto& tx = pair.second;
|
||||
// to-do: expand for all descriptors, but technically only textures are used for this
|
||||
for ( auto& [ _, tx ] : this->metadata.definitions.textures ) {
|
||||
if ( values.count(tx.name) == 0 ) continue;
|
||||
for ( auto& layout : this->descriptorSetLayoutBindings ) {
|
||||
if ( layout.binding != tx.binding ) continue;
|
||||
layout.descriptorCount = values.at(tx.name);
|
||||
for ( auto& [setIndex, bindings] : this->descriptorSetLayoutBindings ) {
|
||||
for ( auto& layout : bindings ) {
|
||||
if ( layout.binding != tx.binding ) continue;
|
||||
layout.descriptorCount = values.at(tx.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ext::vulkan::Shader::Metadata::Definition ext::vulkan::Shader::getDefinition( const uf::stl::string& name ) {
|
||||
#define SEARCH_DEFINITION(definition) for ( auto& [ _, def ] : definition ) if ( def.name == name ) return def;
|
||||
|
||||
SEARCH_DEFINITION(metadata.definitions.inputs);
|
||||
SEARCH_DEFINITION(metadata.definitions.outputs);
|
||||
SEARCH_DEFINITION(metadata.definitions.textures);
|
||||
SEARCH_DEFINITION(metadata.definitions.uniforms);
|
||||
SEARCH_DEFINITION(metadata.definitions.storage);
|
||||
SEARCH_DEFINITION(metadata.definitions.accelerationStructure);
|
||||
SEARCH_DEFINITION(metadata.definitions.pushConstants);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// JSON shit
|
||||
#if 0 && UF_SHADER_PARSE_AS_JSON
|
||||
uf::Serializer ext::vulkan::Shader::getUniformJson( const uf::stl::string& name, bool cache ) {
|
||||
|
||||
@ -40,6 +40,7 @@ uint8_t ext::vulkan::settings::msaa = 1;
|
||||
bool ext::vulkan::settings::defaultStageBuffers = true;
|
||||
bool ext::vulkan::settings::defaultDeferBufferDestroy = true;
|
||||
bool ext::vulkan::settings::defaultCommandBufferImmediate = true;
|
||||
bool ext::vulkan::settings::nBufferedUbos = true;
|
||||
size_t ext::vulkan::settings::defaultTimeout = UINT64_MAX; // 100000000000;
|
||||
|
||||
size_t ext::vulkan::settings::viewCount = 2;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user