Adding bindless material descriptors

This commit is contained in:
Dynamitos
2024-06-18 19:19:05 +02:00
parent cff14981ff
commit f6ebbc2067
23 changed files with 387 additions and 274 deletions
+2
View File
@@ -64,7 +64,9 @@ class DescriptorSet {
virtual void updateBuffer(uint32 binding, PShaderBuffer ShaderBuffer) = 0;
virtual void updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer uniformBuffer) = 0;
virtual void updateSampler(uint32 binding, PSampler sampler) = 0;
virtual void updateSampler(uint32_t binding, uint32 dstArrayIndex, Gfx::PSampler samplerState) = 0;
virtual void updateTexture(uint32 binding, PTexture texture, PSampler samplerState = nullptr) = 0;
virtual void updateTexture(uint32 binding, uint32 dstArrayIndex, PTexture texture) = 0;
virtual void updateTextureArray(uint32_t binding, Array<PTexture> texture) = 0;
bool operator<(PDescriptorSet other);
+6
View File
@@ -194,6 +194,12 @@ DECLARE_REF(TaskShader)
DECLARE_REF(MeshShader)
DECLARE_REF(FragmentShader)
DECLARE_REF(ComputeShader)
DECLARE_REF(RayGenShader)
DECLARE_REF(ClosestHitShader)
DECLARE_REF(AnyHitShader)
DECLARE_REF(IntersectionShader)
DECLARE_REF(MissShader)
DECLARE_REF(CallableShader)
DECLARE_REF(RenderPass)
DECLARE_REF(PipelineLayout)
struct LegacyPipelineCreateInfo {
+7 -6
View File
@@ -21,6 +21,7 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics,
basePassLayout->addDescriptorLayout(viewParamsLayout);
basePassLayout->addDescriptorLayout(scene->getLightEnvironment()->getDescriptorLayout());
basePassLayout->addDescriptorLayout(Material::getDescriptorLayout());
lightCullingLayout = graphics->createDescriptorLayout("pLightCullingData");
// oLightIndexList
@@ -37,7 +38,7 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics,
basePassLayout->addDescriptorLayout(lightCullingLayout);
basePassLayout->addPushConstants(Gfx::SePushConstantRange{
.stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT,
.stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
.offset = 0,
.size = sizeof(VertexData::DrawCallOffsets),
});
@@ -162,12 +163,12 @@ void BasePass::render() {
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
command->bindDescriptor({viewParamsSet, vertexData->getVertexDataSet(), vertexData->getInstanceDataSet(),
scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(), opaqueCulling});
for (const auto& drawCall : materialData.instances) {
command->bindDescriptor({viewParamsSet, vertexData->getVertexDataSet(), vertexData->getInstanceDataSet(),
scene->getLightEnvironment()->getDescriptorSet(), drawCall.materialInstance->getDescriptorSet(),
opaqueCulling});
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0,
sizeof(VertexData::DrawCallOffsets), &drawCall.offsets);
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT |
Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
0, sizeof(VertexData::DrawCallOffsets), &drawCall.offsets);
if (graphics->supportMeshShading()) {
command->drawMesh(drawCall.instanceMeshData.size(), 1, 1);
} else {
-1
View File
@@ -65,7 +65,6 @@ void ShaderCompiler::compile() {
OPipelineLayout layout = graphics->createPipelineLayout(pass.baseLayout->getName(), pass.baseLayout);
layout->addDescriptorLayout(vd->getVertexDataLayout());
layout->addDescriptorLayout(vd->getInstanceDataLayout());
layout->addDescriptorLayout(mat->getDescriptorLayout());
permutation.setMaterial(mat->getName());
createShaders(permutation, std::move(layout));
});
+5
View File
@@ -107,6 +107,10 @@ void VertexData::createDescriptors() {
for (auto& mat : materialData) {
for (auto& instance : mat.instances) {
instance.offsets.instanceOffset = instanceData.size();
MaterialOffsets offsets = instance.materialInstance->getMaterialOffsets();
instance.offsets.textureOffset = offsets.textureOffset;
instance.offsets.samplerOffset = offsets.samplerOffset;
instance.offsets.floatOffset = offsets.floatOffset;
// instance.offsets.cullingCounterOffset = cullingOffsets.size();
// instance.numMeshlets = 0;
for (size_t i = 0; i < instance.instanceData.size(); ++i) {
@@ -161,6 +165,7 @@ void VertexData::createDescriptors() {
descriptorSet->updateBuffer(3, primitiveIndicesBuffer);
descriptorSet->updateBuffer(4, vertexIndicesBuffer);
descriptorSet->updateBuffer(5, cullingOffsetBuffer);
Material::updateDescriptor();
}
void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet> loadedMeshlets) {
+3
View File
@@ -22,6 +22,9 @@ class VertexData {
public:
struct DrawCallOffsets {
uint32 instanceOffset = 0;
uint32 textureOffset = 0;
uint32 samplerOffset = 0;
uint32 floatOffset = 0;
};
struct MeshletCullingInfo {
+1 -1
View File
@@ -316,7 +316,7 @@ void RenderCommand::drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, u
vkCmdDrawMeshTasksIndirectEXT(handle, buffer.cast<ShaderBuffer>()->getHandle(), offset, drawCount, stride);
}
void RenderCommand::traceRays() { vkCmdTraceRaysKHR(handle, ); }
void RenderCommand::traceRays() { }
ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool) : graphics(graphics), owner(cmdPool) {
VkCommandBufferAllocateInfo allocInfo = {
+60 -3
View File
@@ -45,7 +45,7 @@ void DescriptorLayout::create() {
VkDescriptorSetLayoutCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.pNext = &bindingFlagsInfo,
.flags = 0,
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
.bindingCount = (uint32)bindings.size(),
.pBindings = bindings.data(),
};
@@ -67,7 +67,7 @@ DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout)
for (uint32 i = 0; i < layout->getBindings().size(); ++i) {
auto& binding = layout->getBindings()[i];
int typeIndex = binding.descriptorType;
perTypeSizes[typeIndex] += 256;
perTypeSizes[typeIndex] += 512;
}
Array<VkDescriptorPoolSize> poolSizes;
for (uint32 i = 0; i < VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; ++i) {
@@ -81,7 +81,7 @@ DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout)
VkDescriptorPoolCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,
.maxSets = maxSets * Gfx::numFramesBuffered,
.poolSizeCount = (uint32)poolSizes.size(),
.pPoolSizes = poolSizes.data(),
@@ -275,6 +275,34 @@ void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState)
boundResources[binding] = vulkanSampler->getHandle();
}
void DescriptorSet::updateSampler(uint32_t binding, uint32 dstArrayIndex, Gfx::PSampler samplerState)
{
PSampler vulkanSampler = samplerState.cast<Sampler>();
if (boundResources[binding] == vulkanSampler->getHandle()) {
return;
}
imageInfos.add(VkDescriptorImageInfo{
.sampler = vulkanSampler->getSampler(),
.imageView = VK_NULL_HANDLE,
.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
});
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = dstArrayIndex,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
.pImageInfo = &imageInfos.back(),
});
boundResources[binding] = vulkanSampler->getHandle();
}
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler samplerState) {
TextureBase* vulkanTexture = texture.cast<TextureBase>().getHandle();
if (boundResources[binding] == vulkanTexture->getHandle()) {
@@ -306,6 +334,35 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
boundResources[binding] = vulkanTexture->getHandle();
}
void DescriptorSet::updateTexture(uint32 binding, uint32 dstArrayIndex, Gfx::PTexture texture)
{
TextureBase* vulkanTexture = texture.cast<TextureBase>().getHandle();
if (boundResources[binding] == vulkanTexture->getHandle()) {
return;
}
// It is assumed that the image is in the correct layout
imageInfos.add(VkDescriptorImageInfo{
.sampler = VK_NULL_HANDLE,
.imageView = vulkanTexture->getView(),
.imageLayout = cast(vulkanTexture->getLayout()),
});
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = dstArrayIndex,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
.pImageInfo = &imageInfos.back(),
});
boundResources[binding] = vulkanTexture->getHandle();
}
void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture> textures) {
// maybe make this a parameter?
uint32 arrayElement = 0;
+2
View File
@@ -52,7 +52,9 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
virtual void updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer) override;
virtual void updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer uniformBuffer) override;
virtual void updateSampler(uint32_t binding, Gfx::PSampler samplerState) override;
virtual void updateSampler(uint32_t binding, uint32 dstArrayIndex, Gfx::PSampler samplerState) override;
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler sampler = nullptr) override;
virtual void updateTexture(uint32 binding, uint32 dstArrayIndex, Gfx::PTexture texture) override;
virtual void updateTextureArray(uint32_t binding, Array<Gfx::PTexture> texture) override;
constexpr bool isCurrentlyInUse() const { return currentlyInUse; }
+8
View File
@@ -528,6 +528,14 @@ void Graphics::pickPhysicalDevice() {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
.pNext = &meshShaderFeatures,
.storageBuffer8BitAccess = true,
.shaderUniformBufferArrayNonUniformIndexing = true,
.shaderSampledImageArrayNonUniformIndexing = true,
.shaderStorageBufferArrayNonUniformIndexing = true,
.descriptorBindingUniformBufferUpdateAfterBind = true,
.descriptorBindingSampledImageUpdateAfterBind = true,
.descriptorBindingStorageBufferUpdateAfterBind = true,
.descriptorBindingPartiallyBound = true,
.runtimeDescriptorArray = true,
.bufferDeviceAddress = true,
};
features = {
+1 -3
View File
@@ -466,6 +466,4 @@ PComputePipeline PipelineCache::createPipeline(Gfx::ComputePipelineCreateInfo co
return result;
}
PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateInfo createInfo) {
}
PRayTracingPipeline PipelineCache::createPipeline(Gfx::RayTracingPipelineCreateInfo createInfo) { return nullptr; }
+5 -8
View File
@@ -108,14 +108,11 @@ Slang::ComPtr<slang::IBlob> Seele::generateShader(const ShaderCreateInfo& create
CHECK_DIAGNOSTICS();
for (size_t i = 0; i < signature->getParameterCount(); ++i) {
auto param = signature->getParameterByIndex(i);
// workaround
if (std::strcmp(param->getName(), "pVertexData") == 0) {
paramMapping[param->getName()] = 1;
} else if (std::strcmp(param->getName(), "pMaterial") == 0) {
paramMapping[param->getName()] = 4;
} else {
paramMapping[param->getName()] = param->getBindingIndex();
}
paramMapping[param->getName()] = param->getBindingIndex();
}
// workaround
paramMapping["pVertexData"] = 1;
paramMapping["pMaterial"] = 4;
return kernelBlob;
}