Adding bindless material descriptors
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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));
|
||||
});
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -22,6 +22,9 @@ class VertexData {
|
||||
public:
|
||||
struct DrawCallOffsets {
|
||||
uint32 instanceOffset = 0;
|
||||
uint32 textureOffset = 0;
|
||||
uint32 samplerOffset = 0;
|
||||
uint32 floatOffset = 0;
|
||||
};
|
||||
|
||||
struct MeshletCullingInfo {
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user