Fixed errors with descriptors input

This commit is contained in:
antopilo
2025-01-08 22:18:46 -05:00
parent b40b0045b9
commit e5671fd47b
8 changed files with 209 additions and 141 deletions

View File

@@ -372,6 +372,8 @@ void RenderPipeline::Execute(PassRenderContext& ctx)
return;
}
std::vector<TextureAttachment> transitionedInputs;
for (auto& pass : RenderPasses)
{

View File

@@ -14,11 +14,14 @@
#include <volk/volk.h>
#include <map>
namespace Nuake
{
class GPUResources
{
private:
bool isDirty = false;
std::map<UUID, Ref<AllocatedBuffer>> Buffers;
std::map<UUID, Ref<VkMesh>> Meshes;
std::map<UUID, Ref<VulkanImage>> Images;
@@ -36,9 +39,11 @@ namespace Nuake
VkDescriptorSet ModelDescriptor;
VkDescriptorSet SamplerDescriptor;
VkDescriptorSet MaterialDescriptor;
VkDescriptorSet TextureDescriptor;
std::map<UUID, uint32_t> BindlessTextureMapping;
public:
VkDescriptorSet TextureDescriptor;
static GPUResources& Get()
{
static GPUResources instance;
@@ -66,6 +71,9 @@ namespace Nuake
std::vector<VkDescriptorSetLayout> GetBindlessLayout();
uint32_t GetBindlessTextureID(const UUID& id);
void RecreateBindlessTextures();
private:
void CreateBindlessLayout();
};

View File

@@ -77,6 +77,16 @@ void VkRenderer::Initialize()
GPUQueue = VkbDevice.get_queue(vkb::QueueType::graphics).value();
GPUQueueFamily = VkbDevice.get_queue_index(vkb::QueueType::graphics).value();
// Init global pool
std::vector<DescriptorAllocator::PoolSizeRatio> sizes =
{
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 8 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 50 }
};
GlobalDescriptorAllocator.InitPool(Device, 1000, sizes);
InitCommands();
InitSync();
@@ -110,15 +120,7 @@ void VkRenderer::Initialize()
rect_indices[4] = 1;
rect_indices[5] = 3;
// Init global pool
std::vector<DescriptorAllocator::PoolSizeRatio> sizes =
{
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 8 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 50 }
};
GlobalDescriptorAllocator.InitPool(Device, 1000, sizes);
GPUResources& resources = GPUResources::Get();

View File

@@ -171,6 +171,36 @@ void GPUResources::CreateBindlessLayout()
builder.AddBinding(0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, MAX_TEXTURES);
TexturesDescriptorLayout = builder.Build(device, VK_SHADER_STAGE_ALL_GRAPHICS);
}
TextureDescriptor = VkRenderer::Get().GetDescriptorAllocator().Allocate(VkRenderer::Get().GetDevice(), TexturesDescriptorLayout);
}
void GPUResources::RecreateBindlessTextures()
{
if (!TextureDescriptor)
{
CreateBindlessLayout();
}
BindlessTextureMapping.clear();
std::vector<VkDescriptorImageInfo> imageInfos(Images.size());
auto allTextures = GetAllTextures();
for (size_t i = 0; i < Images.size(); i++) {
imageInfos[i].imageView = allTextures[i]->GetImageView();
imageInfos[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
BindlessTextureMapping[allTextures[i]->GetID()] = i;
}
VkWriteDescriptorSet write{};
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
write.dstSet = TextureDescriptor;
write.dstBinding = 0; // Binding 0
write.dstArrayElement = 0;
write.descriptorCount = static_cast<uint32_t>(imageInfos.size());
write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
write.pImageInfo = imageInfos.data();
vkUpdateDescriptorSets(VkRenderer::Get().GetDevice(), 1, &write, 0, nullptr);
}
std::vector<VkDescriptorSetLayout> GPUResources::GetBindlessLayout()
@@ -179,10 +209,14 @@ std::vector<VkDescriptorSetLayout> GPUResources::GetBindlessLayout()
CameraDescriptorLayout,
ModelBufferDescriptorLayout,
TriangleBufferDescriptorLayout,
ImageDescriptorLayout,
SamplerDescriptorLayout,
MaterialDescriptorLayout,
TexturesDescriptorLayout
};
return layouts;
}
}
uint32_t GPUResources::GetBindlessTextureID(const UUID & id)
{
return 0;
}

View File

@@ -29,6 +29,7 @@ VkSceneRenderer::~VkSceneRenderer()
{
}
Ref<VkMesh> quadMesh;
void VkSceneRenderer::Init()
{
// Here we will create the pipeline for rendering a scene
@@ -41,6 +42,19 @@ void VkSceneRenderer::Init()
CreatePipelines();
ModelMatrixMapping.clear();
MeshMaterialMapping.clear();
std::vector<Vertex> quadVertices = {
{{-1.0f, -1.0f, 0.0f }, 0.0f, {}, 0.0f },
{{ 1.0f, -1.0f, 0.0f }, 1.0f, {}, 0.0f },
{{ 1.0f, 1.0f, 0.0f }, 1.0f, {}, 1.0f },
{{-1.0f, 1.0f, 0.0f }, 0.0f, {}, 1.0f }
};
std::vector<uint32_t> quadIndices = {
0, 1, 2, 2, 3, 0
};
quadMesh = CreateRef<VkMesh>(quadVertices, quadIndices);
}
void VkSceneRenderer::BeginScene(RenderContext inContext)
@@ -254,7 +268,7 @@ void VkSceneRenderer::CreatePipelines()
ctx.commandBuffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
ctx.renderPass->PipelineLayout,
5, // firstSet
4, // firstSet
1, // descriptorSetCount
&MaterialBufferDescriptor, // pointer to the descriptor set(s)
0, // dynamicOffsetCount
@@ -265,12 +279,15 @@ void VkSceneRenderer::CreatePipelines()
ctx.commandBuffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
ctx.renderPass->PipelineLayout,
6, // firstSet
5, // firstSet
1, // descriptorSetCount
&TextureBufferDescriptor, // pointer to the descriptor set(s)
&GPUResources::Get().TextureDescriptor, // pointer to the descriptor set(s)
0, // dynamicOffsetCount
nullptr // dynamicOffsets
);
vkCmdBindDescriptorSets(ctx.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx.renderPass->PipelineLayout, 3, 1, &SamplerDescriptor, 0, nullptr);
});
gBufferPass.SetRender([&](PassRenderContext& ctx){
@@ -312,18 +329,6 @@ void VkSceneRenderer::CreatePipelines()
Ref<Material> material = m->GetMaterial();
Ref<VulkanImage> albedo = GPUResources::Get().GetTexture(material->AlbedoImage);
//bind a texture
VkDescriptorSet imageSet = vk.GetCurrentFrame().FrameDescriptors.Allocate(vk.GetDevice(), ImageDescriptorLayout);
{
DescriptorWriter writer;
writer.WriteImage(0, albedo->GetImageView(), SamplerNearest, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
writer.UpdateSet(vk.GetDevice(), imageSet);
}
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx.renderPass->PipelineLayout, 3, 1, &imageSet, 0, nullptr);
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx.renderPass->PipelineLayout, 4, 1, &SamplerDescriptor, 0, nullptr);
modelPushConstant.Index = ModelMatrixMapping[entity.GetID()];
modelPushConstant.MaterialIndex = MeshMaterialMapping[vkMesh->GetID()];
@@ -352,8 +357,74 @@ void VkSceneRenderer::CreatePipelines()
shadingPass.AddInput("Albedo"); // We need to sync those
shadingPass.SetPreRender([](PassRenderContext& ctx) {});
shadingPass.SetRender([](PassRenderContext& ctx) {});
shadingPass.SetPreRender([&](PassRenderContext& ctx) {
std::vector<VkDescriptorSet> descriptors2 = { CameraBufferDescriptors, ModelBufferDescriptor };
vkCmdBindDescriptorSets(
ctx.commandBuffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
ctx.renderPass->PipelineLayout,
0, // firstSet
2, // descriptorSetCount
descriptors2.data(), // pointer to the descriptor set(s)
0, // dynamicOffsetCount
nullptr // dynamicOffsets
);
vkCmdBindDescriptorSets(ctx.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx.renderPass->PipelineLayout, 3, 1, &SamplerDescriptor, 0, nullptr);
// Bind material
vkCmdBindDescriptorSets(
ctx.commandBuffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
ctx.renderPass->PipelineLayout,
4, // firstSet
1, // descriptorSetCount
&MaterialBufferDescriptor, // pointer to the descriptor set(s)
0, // dynamicOffsetCount
nullptr // dynamicOffsets
);
vkCmdBindDescriptorSets(
ctx.commandBuffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
ctx.renderPass->PipelineLayout,
5, // firstSet
1, // descriptorSetCount
&GPUResources::Get().TextureDescriptor, // pointer to the descriptor set(s)
0, // dynamicOffsetCount
nullptr // dynamicOffsets
);
});
shadingPass.SetRender([](PassRenderContext& ctx) {
modelPushConstant.Index = 0;
modelPushConstant.MaterialIndex = 0;
vkCmdPushConstants(
ctx.commandBuffer,
ctx.renderPass->PipelineLayout,
VK_SHADER_STAGE_ALL_GRAPHICS, // Stage matching the pipeline layout
0, // Offset
sizeof(ModelPushConstant), // Size of the push constant
&modelPushConstant // Pointer to the value
);
auto descSet = quadMesh->GetDescriptorSet();
vkCmdBindDescriptorSets(
ctx.commandBuffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
ctx.renderPass->PipelineLayout,
2, // firstSet
1, // descriptorSetCount
&descSet, // pointer to the descriptor set(s)
0, // dynamicOffsetCount
nullptr // dynamicOffsets
);
vkCmdBindIndexBuffer(ctx.commandBuffer, quadMesh->GetIndexBuffer()->GetBuffer(), 0, VK_INDEX_TYPE_UINT32);
vkCmdDrawIndexed(ctx.commandBuffer, quadMesh->GetIndexBuffer()->GetSize() / sizeof(uint32_t), 1, 0, 0, 0);
});
GBufferPipeline.Build();
}
@@ -392,26 +463,6 @@ void VkSceneRenderer::BuildMatrixBuffer()
ZoneScopedN("Build Matrix Buffer");
auto& scene = Context.CurrentScene;
std::map<UUID, uint32_t> TextureIDMapping;
auto allTextures = GPUResources::Get().GetAllTextures();
std::vector<VkDescriptorImageInfo> imageInfos(allTextures.size());
for (size_t i = 0; i < allTextures.size(); i++) {
imageInfos[i].imageView = allTextures[i]->GetImageView();
imageInfos[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
TextureIDMapping[allTextures[i]->GetID()] = i;
}
VkWriteDescriptorSet write{};
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
write.dstSet = TextureBufferDescriptor;
write.dstBinding = 0; // Binding 0
write.dstArrayElement = 0;
write.descriptorCount = static_cast<uint32_t>(imageInfos.size());
write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
write.pImageInfo = imageInfos.data();
vkUpdateDescriptorSets(VkRenderer::Get().GetDevice(), 1, &write, 0, nullptr);
std::array<Matrix4, MAX_MODEL_MATRIX> allTransforms;
std::array<MaterialBufferStruct, MAX_MATERIAL> allMaterials;
@@ -447,6 +498,7 @@ void VkSceneRenderer::BuildMatrixBuffer()
continue;
}
auto& res = GPUResources::Get();
// TODO: Avoid duplicated materials
MaterialBufferStruct materialBuffer = {};
materialBuffer.hasAlbedo = material->HasAlbedo();
@@ -458,11 +510,11 @@ void VkSceneRenderer::BuildMatrixBuffer()
materialBuffer.aoValue = material->data.u_AOValue;
materialBuffer.hasRoughness = material->HasRoughness();
materialBuffer.roughnessValue = material->data.u_RoughnessValue;
materialBuffer.albedoTextureId = material->HasAlbedo() ? TextureIDMapping[material->AlbedoImage] : 0;
materialBuffer.normalTextureId = material->HasNormal() ? TextureIDMapping[material->NormalImage] : 0;
materialBuffer.metalnessTextureId = material->HasMetalness() ? TextureIDMapping[material->MetalnessImage] : 0;
materialBuffer.aoTextureId = material->HasAO() ? TextureIDMapping[material->AOImage] : 0;
materialBuffer.roughnessTextureId = material->HasRoughness() ? TextureIDMapping[material->RoughnessImage] : 0;
materialBuffer.albedoTextureId = material->HasAlbedo() ? res.GetBindlessTextureID(material->AlbedoImage) : 0;
materialBuffer.normalTextureId = material->HasNormal() ? res.GetBindlessTextureID(material->NormalImage) : 0;
materialBuffer.metalnessTextureId = material->HasMetalness() ? res.GetBindlessTextureID(material->MetalnessImage) : 0;
materialBuffer.aoTextureId = material->HasAO() ? res.GetBindlessTextureID(material->AOImage) : 0;
materialBuffer.roughnessTextureId = material->HasRoughness() ? res.GetBindlessTextureID(material->RoughnessImage) : 0;
allMaterials[currentMaterialIndex] = materialBuffer;
MeshMaterialMapping[m->GetVkMesh()->GetID()] = currentMaterialIndex;

View File

@@ -1,7 +1,4 @@
[[vk::binding(0, 3)]]
Texture2D<float4> albedo : register(t1); // Texture binding at slot t0
[[vk::binding(0, 4)]]
SamplerState mySampler : register(s0); // Sampler binding at slot s0
struct Material
@@ -16,21 +13,20 @@ struct Material
float roughnessValue;
float aoValue;
};
[[vk::binding(0, 5)]]
[[vk::binding(0, 4)]]
StructuredBuffer<Material> material;
[[vk::binding(0, 5)]]
Texture2D textures[]; // Array de 500 textures
struct PSInput {
float4 Position : SV_Position;
float3 Color : TEXCOORD0;
float2 UV : TEXCOORD1;
float3 Normal : TEXCOORD2;
float3x3 TBN : TEXCOORD3;
float2 UV : TEXCOORD0;
float4x4 InvProj : TEXCOORD1;
float4x4 InvView : TEXCOORD2;
};
struct PSOutput {
float4 oColor0 : SV_TARGET;
float4 oNormal : SV_TARGET1;
float4 oMaterial : SV_TARGET2;
};
struct ModelPushConstant
@@ -46,58 +42,7 @@ PSOutput main(PSInput input)
{
PSOutput output;
Material inMaterial = material[pushConstants.materialIndex];
// NORMAL
// TODO use TBN matrix
float3 normal = float3(0.0, 0.0f, 1.0f);
if(inMaterial.hasNormal == 1)
{
// Sample from texture.
}
output.oColor0 = float4(1, 0, 0, 1);
normal = mul(input.TBN, normal);
normal = normal / 2.0f + 0.5f;
output.oNormal = float4(normal, 1.0f);
// MATERIAL
// ALBEDO COLOR
float4 albedoColor = float4(inMaterial.albedo.xyz, 1.0f);
if(inMaterial.hasAlbedo == 1)
{
float4 albedoTextureSample = albedo.Sample(mySampler, input.UV);
// Alpha cutout?
if(albedoTextureSample.a < 0.001f)
{
discard;
}
albedoColor.xyz = albedoTextureSample.xyz;
}
output.oColor0 = albedoColor;
// MATERIAL PROPERTIES
float metalnessValue = inMaterial.metalnessValue;
if(inMaterial.hasMetalness == 1)
{
// TODO: Sample from metal texture
}
float aoValue = inMaterial.aoValue;
if(inMaterial.hasAO == 1)
{
// TODO: Sample from AO texture
}
float roughnessValue = inMaterial.roughnessValue;
if(inMaterial.hasRoughness == 1)
{
// TODO: Sample from roughness texture
}
float3 materialOuput = float3(inMaterial.metalnessValue, inMaterial.aoValue, inMaterial.roughnessValue);
output.oMaterial = float4(materialOuput, 1.0f);
return output;
}

View File

@@ -37,34 +37,62 @@ ModelPushConstant pushConstants;
// Outputs
struct VSOutput {
float4 Position : SV_Position;
float3 Color : TEXCOORD0;
float2 UV : TEXCOORD1;
float3 Normal : TEXCOORD2;
float3x3 TBN : TEXCOORD3;
float2 UV : TEXCOORD0;
float4x4 InvProj : TEXCOORD1;
float4x4 InvView : TEXCOORD2;
};
float4x4 inverse(float4x4 m) {
float n11 = m[0][0], n12 = m[1][0], n13 = m[2][0], n14 = m[3][0];
float n21 = m[0][1], n22 = m[1][1], n23 = m[2][1], n24 = m[3][1];
float n31 = m[0][2], n32 = m[1][2], n33 = m[2][2], n34 = m[3][2];
float n41 = m[0][3], n42 = m[1][3], n43 = m[2][3], n44 = m[3][3];
float t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44;
float t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44;
float t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44;
float t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
float det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;
float idet = 1.0f / det;
float4x4 ret;
ret[0][0] = t11 * idet;
ret[0][1] = (n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44) * idet;
ret[0][2] = (n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44) * idet;
ret[0][3] = (n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43) * idet;
ret[1][0] = t12 * idet;
ret[1][1] = (n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44) * idet;
ret[1][2] = (n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44) * idet;
ret[1][3] = (n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43) * idet;
ret[2][0] = t13 * idet;
ret[2][1] = (n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44) * idet;
ret[2][2] = (n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44) * idet;
ret[2][3] = (n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43) * idet;
ret[3][0] = t14 * idet;
ret[3][1] = (n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34) * idet;
ret[3][2] = (n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34) * idet;
ret[3][3] = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * idet;
return ret;
}
// Main vertex shader
VSOutput main(uint vertexIndex : SV_VertexID)
{
VSOutput output;
Camera camData = camera[0];
output.InvProj = inverse(camData.proj);
output.InvView = inverse(camData.view);
ModelData modelData = model[pushConstants.modelIndex];
// Load vertex data from the buffer
Vertex v = vertexBuffer[vertexIndex];
// Output the position of each vertex
output.Position = mul(camData.proj, mul(camData.view, mul(modelData.model, float4(v.position, 1.0f))));
output.Color = normalize(float3(v.position.xyz));
output.UV = float2(v.uv_x, v.uv_y);
output.Normal = normalize(v.normal);
float3 T = normalize(mul((float3x3)modelData.model, normalize(v.tangent.xyz)));
float3 B = normalize(mul((float3x3)modelData.model, normalize(v.bitangent.xyz)));
float3 N = normalize(mul((float3x3)modelData.model, normalize(v.normal)).xyz);
output.TBN = transpose(float3x3(T, B, N));
return output;
}

View File

@@ -1,7 +1,4 @@
[[vk::binding(0, 3)]]
Texture2D<float4> albedo : register(t1); // Texture binding at slot t0
[[vk::binding(0, 4)]]
SamplerState mySampler : register(s0); // Sampler binding at slot s0
struct Material
@@ -22,11 +19,11 @@ struct Material
int aoTextureId;
};
[[vk::binding(0, 5)]]
StructuredBuffer<Material> material;
[[vk::binding(0, 4)]]
StructuredBuffer<Material> material; // array de 2000 materials
[[vk::binding(0, 6)]]
Texture2D textures[];
[[vk::binding(0, 5)]]
Texture2D textures[]; // Array de 500 textures
struct PSInput {
float4 Position : SV_Position;