Vulkan: descriptor binding without using shader reflection and using mutable descriptors
This commit is contained in:
@@ -115,12 +115,15 @@ struct StackVector
|
||||
constexpr void push_back(T&& item) { items[last++] = static_cast<T&&>(item); }
|
||||
constexpr void pop_back() { if (!empty()) items[--last] = {}; }
|
||||
constexpr void clear() { for (unsigned i = 0; i < count; ++i) items[i] = {}; last = 0; }
|
||||
constexpr T* data() { return items; }
|
||||
constexpr const T* data() const { return items; }
|
||||
constexpr T* begin() { return items; }
|
||||
constexpr T* end() { return items + last; }
|
||||
constexpr const T& back() const { return items[last - 1]; }
|
||||
constexpr T& back() { return items[0]; }
|
||||
constexpr const T& front() const { return items[last - 1]; }
|
||||
constexpr T& back() { return items[last - 1]; }
|
||||
constexpr const T& front() const { return items[0]; }
|
||||
constexpr T& front() { return items[0]; }
|
||||
constexpr T& emplace_back() { push_back({}); return back(); }
|
||||
constexpr const T& operator[](unsigned index) const { return items[index]; }
|
||||
constexpr T& operator[](unsigned index) { return items[index]; }
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -345,9 +345,7 @@
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Utility\dxcapi.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Utility\flat_hash_map.hpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Utility\GLSL.std.450.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Utility\include\spirv\unified1\spirv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Utility\sal.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Utility\spirv_reflect.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Utility\stb_image.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Utility\stb_image_write.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Utility\stb_truetype.h" />
|
||||
@@ -629,16 +627,6 @@
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)wiPhysics_Jolt.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)wiRenderPath3D_PathTracing.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Utility\samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_1spp.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Utility\spirv_reflect.c">
|
||||
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
|
||||
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
|
||||
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">false</CompileAsWinRT>
|
||||
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsWinRT>
|
||||
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">false</CompileAsWinRT>
|
||||
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsWinRT>
|
||||
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsWinRT>
|
||||
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsWinRT>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Utility\stb_vorbis.c">
|
||||
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsWinRT>
|
||||
<CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsWinRT>
|
||||
|
||||
@@ -399,12 +399,6 @@
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)wiSDLInput.h">
|
||||
<Filter>ENGINE\Input</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Utility\spirv_reflect.h">
|
||||
<Filter>UTILITY</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Utility\include\spirv\unified1\spirv.h">
|
||||
<Filter>UTILITY</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Utility\volk.h">
|
||||
<Filter>UTILITY</Filter>
|
||||
</ClInclude>
|
||||
@@ -1697,9 +1691,6 @@
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Utility\stb_vorbis.c">
|
||||
<Filter>UTILITY</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Utility\spirv_reflect.c">
|
||||
<Filter>UTILITY</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)wiShaderCompiler.cpp">
|
||||
<Filter>ENGINE\Graphics\API</Filter>
|
||||
</ClCompile>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -32,80 +32,6 @@
|
||||
#define vulkan_assert(cond, fname) { wilog_assert(cond, "Vulkan error: %s failed with %s (%s:%d)", fname, string_VkResult(res), relative_path(__FILE__), __LINE__); }
|
||||
#define vulkan_check(call) [&]() { VkResult res = call; vulkan_assert((res >= VK_SUCCESS), extract_function_name(#call).c_str()); return res; }()
|
||||
|
||||
namespace wi::graphics
|
||||
{
|
||||
struct PSOLayoutHash
|
||||
{
|
||||
VkPushConstantRange push = {};
|
||||
struct Item
|
||||
{
|
||||
bool used = true;
|
||||
VkImageViewType viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
VkDescriptorSetLayoutBinding binding = {};
|
||||
};
|
||||
wi::vector<Item> items;
|
||||
size_t hash = 0;
|
||||
|
||||
inline bool operator==(const PSOLayoutHash& other) const
|
||||
{
|
||||
if (hash != other.hash)
|
||||
return false;
|
||||
if (items.size() != other.items.size())
|
||||
return false;
|
||||
for (size_t i = 0; i < items.size(); ++i)
|
||||
{
|
||||
const Item& a = items[i];
|
||||
const Item& b = other.items[i];
|
||||
if (
|
||||
a.used != b.used ||
|
||||
a.viewType != b.viewType ||
|
||||
a.binding.binding != b.binding.binding ||
|
||||
a.binding.descriptorCount != b.binding.descriptorCount ||
|
||||
a.binding.descriptorType != b.binding.descriptorType ||
|
||||
a.binding.stageFlags != b.binding.stageFlags ||
|
||||
a.binding.pImmutableSamplers != b.binding.pImmutableSamplers
|
||||
)
|
||||
return false;
|
||||
}
|
||||
return
|
||||
push.offset == other.push.offset &&
|
||||
push.size == other.push.size &&
|
||||
push.stageFlags == other.push.stageFlags;
|
||||
}
|
||||
inline void embed_hash()
|
||||
{
|
||||
hash = 0;
|
||||
for (auto& x : items)
|
||||
{
|
||||
wi::helper::hash_combine(hash, x.used);
|
||||
wi::helper::hash_combine(hash, x.viewType);
|
||||
wi::helper::hash_combine(hash, x.binding.binding);
|
||||
wi::helper::hash_combine(hash, x.binding.descriptorCount);
|
||||
wi::helper::hash_combine(hash, x.binding.descriptorType);
|
||||
wi::helper::hash_combine(hash, x.binding.stageFlags);
|
||||
}
|
||||
wi::helper::hash_combine(hash, push.offset);
|
||||
wi::helper::hash_combine(hash, push.size);
|
||||
wi::helper::hash_combine(hash, push.stageFlags);
|
||||
}
|
||||
constexpr size_t get_hash() const
|
||||
{
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
}
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct hash<wi::graphics::PSOLayoutHash>
|
||||
{
|
||||
constexpr size_t operator()(const wi::graphics::PSOLayoutHash& hash) const
|
||||
{
|
||||
return hash.get_hash();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace wi::graphics
|
||||
{
|
||||
class GraphicsDevice_Vulkan final : public GraphicsDevice
|
||||
@@ -155,6 +81,7 @@ namespace wi::graphics
|
||||
VkPhysicalDeviceRayQueryFeaturesKHR raytracing_query_features = {};
|
||||
VkPhysicalDeviceFragmentShadingRateFeaturesKHR fragment_shading_rate_features = {};
|
||||
VkPhysicalDeviceConditionalRenderingFeaturesEXT conditional_rendering_features = {};
|
||||
VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT mutable_descriptor_features = {};
|
||||
VkPhysicalDeviceDepthClipEnableFeaturesEXT depth_clip_enable_features = {};
|
||||
VkPhysicalDeviceImageViewMinLodFeaturesEXT image_view_min_lod_features = {};
|
||||
VkPhysicalDeviceMeshShaderFeaturesEXT mesh_shader_features = {};
|
||||
@@ -196,6 +123,25 @@ namespace wi::graphics
|
||||
VkImageView nullImageViewCubeArray = VK_NULL_HANDLE;
|
||||
VkImageView nullImageView3D = VK_NULL_HANDLE;
|
||||
|
||||
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
|
||||
|
||||
enum DESCRIPTOR_SET
|
||||
{
|
||||
DESCRIPTOR_SET_BINDINGS,
|
||||
|
||||
DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER,
|
||||
DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER,
|
||||
DESCRIPTOR_SET_BINDLESS_SAMPLER,
|
||||
DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE,
|
||||
DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE,
|
||||
DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER,
|
||||
DESCRIPTOR_SET_BINDLESS_ACCELERATION_STRUCTURE,
|
||||
|
||||
DESCRIPTOR_SET_COUNT,
|
||||
};
|
||||
VkDescriptorSet descriptor_sets[DESCRIPTOR_SET_COUNT] = {};
|
||||
VkDescriptorSetLayout descriptor_set_layouts[DESCRIPTOR_SET_COUNT] = {};
|
||||
|
||||
struct CommandQueue
|
||||
{
|
||||
VkQueue queue = VK_NULL_HANDLE;
|
||||
@@ -262,17 +208,7 @@ namespace wi::graphics
|
||||
{
|
||||
DescriptorBindingTable table;
|
||||
GraphicsDevice_Vulkan* device;
|
||||
|
||||
wi::vector<VkWriteDescriptorSet> descriptorWrites;
|
||||
wi::vector<VkDescriptorBufferInfo> bufferInfos;
|
||||
wi::vector<VkDescriptorImageInfo> imageInfos;
|
||||
wi::vector<VkBufferView> texelBufferViews;
|
||||
wi::vector<VkWriteDescriptorSetAccelerationStructureKHR> accelerationStructureViews;
|
||||
|
||||
uint32_t uniform_buffer_dynamic_offsets[DESCRIPTORBINDER_CBV_COUNT] = {};
|
||||
|
||||
VkDescriptorSet descriptorSet_graphics = VK_NULL_HANDLE;
|
||||
VkDescriptorSet descriptorSet_compute = VK_NULL_HANDLE;
|
||||
VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
|
||||
|
||||
enum DIRTY_FLAGS
|
||||
{
|
||||
@@ -405,8 +341,7 @@ namespace wi::graphics
|
||||
void predraw(CommandList cmd);
|
||||
void predispatch(CommandList cmd);
|
||||
|
||||
static constexpr uint32_t immutable_sampler_slot_begin = 100;
|
||||
wi::vector<VkSampler> immutable_samplers;
|
||||
VkSampler immutable_samplers[10];
|
||||
|
||||
void set_fence_name(VkFence fence, const char* name);
|
||||
void set_semaphore_name(VkSemaphore semaphore, const char* name);
|
||||
@@ -897,27 +832,6 @@ namespace wi::graphics
|
||||
};
|
||||
wi::allocator::shared_ptr<AllocationHandler> allocationhandler;
|
||||
|
||||
|
||||
struct PSOLayout
|
||||
{
|
||||
wi::allocator::shared_ptr<AllocationHandler> allocationhandler;
|
||||
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
|
||||
VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE;
|
||||
wi::vector<VkDescriptorSet> bindlessSets;
|
||||
uint32_t bindlessFirstSet = 0;
|
||||
~PSOLayout()
|
||||
{
|
||||
if (allocationhandler == nullptr)
|
||||
return;
|
||||
allocationhandler->destroylocker.lock();
|
||||
uint64_t framecount = allocationhandler->framecount;
|
||||
allocationhandler->destroyer_pipelineLayouts.push_back(std::make_pair(pipelineLayout, framecount));
|
||||
allocationhandler->destroyer_descriptorSetLayouts.push_back(std::make_pair(descriptorSetLayout, framecount));
|
||||
allocationhandler->destroylocker.unlock();
|
||||
}
|
||||
};
|
||||
mutable wi::unordered_map<PSOLayoutHash, wi::allocator::shared_ptr<PSOLayout>> pso_layout_cache;
|
||||
mutable std::mutex pso_layout_cache_mutex;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user