diff --git a/CMakePresets.json b/CMakePresets.json index d45a509..0c49649 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -27,8 +27,8 @@ "CMAKE_EXPORT_COMPILE_COMMANDS": true, "CMAKE_MAKE_PROGRAM": "ninja", "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake", - "DXC_SHADER_FLAGS": "-Zi", - "GLSLC_SHADER_FLAGS": "-g" + "DXC_SHADER_FLAGS": "-Zi;-D_DEBUG", + "GLSLC_SHADER_FLAGS": "-g;-D_DEBUG" }, "condition": { "type": "equals", @@ -45,8 +45,8 @@ "CMAKE_EXPORT_COMPILE_COMMANDS": true, "CMAKE_MAKE_PROGRAM": "ninja", "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake", - "DXC_SHADER_FLAGS": "-Zi", - "GLSLC_SHADER_FLAGS": "-g" + "DXC_SHADER_FLAGS": "-Zi;-D_DEBUG", + "GLSLC_SHADER_FLAGS": "-g;-D_DEBUG" }, "condition": { "type": "equals", @@ -63,8 +63,8 @@ "CMAKE_EXPORT_COMPILE_COMMANDS": true, "CMAKE_MAKE_PROGRAM": "ninja", "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake", - "DXC_SHADER_FLAGS": "-Zi", - "GLSLC_SHADER_FLAGS": "-g", + "DXC_SHADER_FLAGS": "-Zi;-D_DEBUG", + "GLSLC_SHADER_FLAGS": "-g;-D_DEBUG", "MSVC_DEFINES": "ASTER_NO_BREAK" }, "condition": { diff --git a/samples/03_model_render/asset_loader.cpp b/samples/03_model_render/asset_loader.cpp index 2b4e5f7..078e168 100644 --- a/samples/03_model_render/asset_loader.cpp +++ b/samples/03_model_render/asset_loader.cpp @@ -61,7 +61,7 @@ AssetLoader::LoadHdrImage(Texture *texture, cstr path, cstr name) const ERROR_IF(texture->IsValid(), "Expected invalid image.") THEN_ABORT(-1); i32 x, y, nChannels; - const f32 *data = stbi_loadf(path, &x, &y, &nChannels, 4); + f32 *data = stbi_loadf(path, &x, &y, &nChannels, 4); assert(nChannels == 3); ERROR_IF(!data, "Could not load {}", path) THEN_ABORT(-1); @@ -75,6 +75,8 @@ AssetLoader::LoadHdrImage(Texture *texture, cstr path, cstr name) const stagingBuffer.Init(m_ResourceManager->m_Device, (sizeof *data) * x * y * 4, "HDR Staging Buffer"); stagingBuffer.Write(m_ResourceManager->m_Device, 0, stagingBuffer.GetSize(), data); + stbi_image_free(data); + #pragma region Setup Copy/Sync primitives vk::BufferImageCopy2 copyRegion = { .bufferOffset = 0, diff --git a/samples/03_model_render/model_render.cpp b/samples/03_model_render/model_render.cpp index 056192a..ca5f7ef 100644 --- a/samples/03_model_render/model_render.cpp +++ b/samples/03_model_render/model_render.cpp @@ -139,6 +139,8 @@ main(int, char **) PhysicalDevices physicalDevices = {&window, &context}; PhysicalDevice deviceToUse = FindSuitableDevice(physicalDevices); + usize physicalDeviceOffsetAlignment = deviceToUse.m_DeviceProperties.limits.minUniformBufferOffsetAlignment; + INFO("Using {} as the primary device.", deviceToUse.m_DeviceProperties.deviceName.data()); Features enabledDeviceFeatures = { @@ -197,14 +199,14 @@ main(int, char **) lightManager.Update(); vk::DescriptorPool descriptorPool; - vk::DescriptorSet descriptorSet; + vk::DescriptorSet perFrameDescriptor; { vk::DescriptorSetLayout descriptorSetLayout = pipeline.m_SetLayouts[1]; eastl::array poolSizes = { vk::DescriptorPoolSize{ .type = vk::DescriptorType::eUniformBuffer, - .descriptorCount = 1, + .descriptorCount = 3, }, }; vk::DescriptorPoolCreateInfo descriptorPoolCreateInfo = { @@ -216,7 +218,7 @@ main(int, char **) .descriptorSetCount = 1, .pSetLayouts = &descriptorSetLayout, }; - AbortIfFailed(device.m_Device.allocateDescriptorSets(&descriptorSetAllocateInfo, &descriptorSet)); + AbortIfFailed(device.m_Device.allocateDescriptorSets(&descriptorSetAllocateInfo, &perFrameDescriptor)); } vk::Extent2D internalResolution = {1920, 1080}; @@ -224,22 +226,50 @@ main(int, char **) CameraController cameraController = {vec3{0.0f, 0.0f, 2.0f}, vec3{0.0f}, 70_deg, Cast(swapchain.m_Extent.width) / Cast(swapchain.m_Extent.height)}; + usize uboSize = 0; + usize cameraSize = sizeof cameraController.m_Camera; + uboSize += ClosestMultiple(cameraSize, physicalDeviceOffsetAlignment); + usize lightOffset = uboSize; + usize lightingSize = sizeof environment + sizeof lightManager.m_MetaInfo; + uboSize += ClosestMultiple(lightingSize, physicalDeviceOffsetAlignment); + + u8 *data = new u8[uboSize]; + memcpy(data, &cameraController.m_Camera, cameraSize); + memcpy(data + lightOffset, &environment, sizeof environment); + memcpy(data + lightOffset + sizeof environment, &lightManager.m_MetaInfo, sizeof lightManager.m_MetaInfo); + UniformBuffer ubo; - ubo.Init(&device, sizeof cameraController.m_Camera, "Camera UBO"); - ubo.Write(&device, 0, sizeof cameraController.m_Camera, &cameraController.m_Camera); - vk::DescriptorBufferInfo descriptorBufferInfo = { + ubo.Init(&device, uboSize, "Desc1 UBO"); + ubo.Write(&device, 0, ubo.GetSize(), data); + + delete[] data; + + vk::DescriptorBufferInfo cameraBufferInfo = { .buffer = ubo.m_Buffer, .offset = 0, - .range = ubo.GetSize(), + .range = cameraSize, + }; + vk::DescriptorBufferInfo lightingBufferInfo = { + .buffer = ubo.m_Buffer, + .offset = lightOffset, + .range = lightingSize, }; eastl::array writeDescriptors = { vk::WriteDescriptorSet{ - .dstSet = descriptorSet, + .dstSet = perFrameDescriptor, .dstBinding = 0, .dstArrayElement = 0, .descriptorCount = 1, .descriptorType = vk::DescriptorType::eUniformBuffer, - .pBufferInfo = &descriptorBufferInfo, + .pBufferInfo = &cameraBufferInfo, + }, + vk::WriteDescriptorSet{ + .dstSet = perFrameDescriptor, + .dstBinding = 1, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eUniformBuffer, + .pBufferInfo = &lightingBufferInfo, }, }; device.m_Device.updateDescriptorSets(Cast(writeDescriptors.size()), writeDescriptors.data(), 0, nullptr); @@ -376,6 +406,11 @@ main(int, char **) bool showPrefilter = false; bool useSpecular = true; + constexpr u32 USE_DIFFUSE_BIT = 1; + constexpr u32 USE_SPECULAR_BIT = 1 << 1; + constexpr u32 SHOW_DIFFUSE_BIT = 1 << 2; + constexpr u32 SHOW_PREFILTER_BIT = 1 << 3; + i32 height = Cast(internalResolution.height); f32 camPitch = glm::degrees(cameraController.m_Pitch); f32 camYaw = glm::degrees(cameraController.m_Yaw); @@ -548,45 +583,40 @@ main(int, char **) cmd.setScissor(0, 1, &scissor); cmd.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline.m_Layout, 0, 1, &resourceManager.m_DescriptorSet, 0, nullptr); - cmd.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline.m_Layout, 1, 1, &descriptorSet, 0, nullptr); + + cmd.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline.m_Layout, 1, 1, &perFrameDescriptor, 0, + nullptr); + cmd.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline.m_Layout, 1, 1, &perFrameDescriptor, 0, + nullptr); cmd.bindIndexBuffer(model.m_IndexBuffer.m_Buffer, 0, vk::IndexType::eUint32); cmd.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline.m_Pipeline); + u32 flags = 0; + if (useSpecular) + { + flags |= USE_SPECULAR_BIT; + } + if (useDiffuse) + { + flags |= USE_DIFFUSE_BIT; + } + if (showPrefilter) + { + flags |= SHOW_PREFILTER_BIT; + } + if (showDiffuse) + { + flags |= SHOW_DIFFUSE_BIT; + } + u32 pcbOffset = 0; cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, pcbOffset, sizeof model.m_Handles, &model.m_Handles); pcbOffset += sizeof model.m_Handles; - - Environment thisFrameEnvBuffers = environment; - if (showDiffuse) - { - thisFrameEnvBuffers.m_Skybox = environment.m_Diffuse; - } - else if (showPrefilter) - { - thisFrameEnvBuffers.m_Skybox = environment.m_Prefilter; - } - - if (!useDiffuse) - { - thisFrameEnvBuffers.m_Diffuse = {}; - } - if (!useSpecular) - { - thisFrameEnvBuffers.m_BrdfLut = {}; - thisFrameEnvBuffers.m_Prefilter = {}; - } - - assert(pcbOffset == 16); - cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, pcbOffset, sizeof thisFrameEnvBuffers, - &thisFrameEnvBuffers); - pcbOffset += sizeof thisFrameEnvBuffers; - - cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, pcbOffset, sizeof lightManager.m_MetaInfo, - &lightManager.m_MetaInfo); - pcbOffset += sizeof lightManager.m_MetaInfo; + cmd.pushConstants(pipeline.m_Layout, vk::ShaderStageFlagBits::eAll, pcbOffset, sizeof flags, &flags); + pcbOffset += sizeof flags; for (auto &prim : model.m_MeshPrimitives) { diff --git a/samples/03_model_render/pipeline_utils.cpp b/samples/03_model_render/pipeline_utils.cpp index df8d019..10918e1 100644 --- a/samples/03_model_render/pipeline_utils.cpp +++ b/samples/03_model_render/pipeline_utils.cpp @@ -43,6 +43,18 @@ CreatePipeline(const Device *device, vk::Format attachmentFormat, const GpuResou .descriptorCount = 1, .stageFlags = vk::ShaderStageFlagBits::eAll, }, + vk::DescriptorSetLayoutBinding{ + .binding = 1, + .descriptorType = vk::DescriptorType::eUniformBuffer, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eAll, + }, + vk::DescriptorSetLayoutBinding{ + .binding = 2, + .descriptorType = vk::DescriptorType::eUniformBuffer, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eAll, + }, }; vk::DescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = { .bindingCount = Cast(descriptorSetLayoutBindings.size()), @@ -57,7 +69,7 @@ CreatePipeline(const Device *device, vk::Format attachmentFormat, const GpuResou vk::PushConstantRange pushConstantRange = { .stageFlags = vk::ShaderStageFlagBits::eAll, .offset = 0, - .size = 52, + .size = 32, }; vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo = { @@ -192,6 +204,18 @@ CreateBackgroundPipeline(const Device *device, vk::Format attachmentFormat, cons .descriptorCount = 1, .stageFlags = vk::ShaderStageFlagBits::eAll, }, + vk::DescriptorSetLayoutBinding{ + .binding = 1, + .descriptorType = vk::DescriptorType::eUniformBuffer, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eAll, + }, + vk::DescriptorSetLayoutBinding{ + .binding = 2, + .descriptorType = vk::DescriptorType::eUniformBuffer, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eAll, + }, }; vk::DescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = { .bindingCount = Cast(descriptorSetLayoutBindings.size()), @@ -206,7 +230,7 @@ CreateBackgroundPipeline(const Device *device, vk::Format attachmentFormat, cons vk::PushConstantRange pushConstantRange = { .stageFlags = vk::ShaderStageFlagBits::eAll, .offset = 0, - .size = 52, + .size = 32, }; vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo = { diff --git a/samples/03_model_render/shader/background.ps.hlsl b/samples/03_model_render/shader/background.ps.hlsl index 8d5bb82..3ebc5f5 100644 --- a/samples/03_model_render/shader/background.ps.hlsl +++ b/samples/03_model_render/shader/background.ps.hlsl @@ -15,7 +15,23 @@ PS_Output main(PS_Input StageInput) PS_Output StageOutput; float3 Direction = normalize(StageInput.WorldPosition - Camera.Position.xyz); - float4 Color = TextureCubes[PushConstant.EnvCubeHandle].Sample(ImmutableSamplers[PushConstant.EnvCubeHandle], Direction); +#ifndef _DEBUG + float4 Color = TextureCubes[Lights.EnvCubeHandle].Sample(ImmutableSamplers[Lights.EnvCubeHandle], Direction); +#else + float4 Color; + if ((PushConstant.DebugFlags & SHOW_DIFFUSE_BIT) > 0) + { + Color = TextureCubes[Lights.DiffuseIrradianceHandle].Sample(ImmutableSamplers[Lights.DiffuseIrradianceHandle], Direction); + } + else if ((PushConstant.DebugFlags & SHOW_PREFILTER_BIT) > 0) + { + Color = TextureCubes[Lights.PrefilterHandle].Sample(ImmutableSamplers[Lights.PrefilterHandle], Direction); + } + else + { + Color = TextureCubes[Lights.EnvCubeHandle].Sample(ImmutableSamplers[Lights.EnvCubeHandle], Direction); + } +#endif StageOutput.Color = float4(Uncharted2Tonemap(Color.rgb), Color.a); return StageOutput; diff --git a/samples/03_model_render/shader/graphics_structs.hlsli b/samples/03_model_render/shader/graphics_structs.hlsli index b19a3e3..f7d7e8d 100644 --- a/samples/03_model_render/shader/graphics_structs.hlsli +++ b/samples/03_model_render/shader/graphics_structs.hlsli @@ -2,34 +2,53 @@ struct CameraData { - float4x4 View; - float4x4 Projection; - float4x4 InvView; - float4x4 InvProjection; - float4 Position; + float4x4 View; // 64 + float4x4 Projection; // 128 + float4x4 InvView; // 192 + float4x4 InvProjection; // 256 + float4 Position; // 272 +}; + +struct Lighting +{ + uint EnvCubeHandle; // 4 + uint DiffuseIrradianceHandle; // 8 + uint PrefilterHandle; // 12 + uint BrdfLutHandle; // 16 + uint LightHandle; // 20 + uint PointLightIndexer; // 24 + uint DirectionalLightIndexer; // 28 +}; + +struct ModelHandles +{ + uint VertexBufferHandle; // 4 + uint VertexDataHandle; // 8 + uint MaterialBufferHandle; // 12 + uint NodeBufferHandle; // 16 }; struct Block { - uint VertexBufferHandle; - uint VertexDataHandle; - uint MaterialBufferHandle; - uint NodeBufferHandle; + uint VertexBufferHandle; // 4 + uint VertexDataHandle; // 8 + uint MaterialBufferHandle; // 12 + uint NodeBufferHandle; // 16 - uint EnvCubeHandle; - uint DiffuseIrradianceHandle; - uint PrefilterHandle; - uint BrdfLutHandle; + uint DebugFlags; // 20 - uint LightHandle; - uint PointLightIndexer; - uint DirectionalLightIndexer; - - int MaterialIdx; - uint NodeIdx; + int MaterialIdx; // 24 + uint NodeIdx; // 28 }; +static const uint USE_DIFFUSE_BIT = 1; +static const uint USE_SPECULAR_BIT = 2; +static const uint SHOW_DIFFUSE_BIT = 4; +static const uint SHOW_PREFILTER_BIT = 8; + [[vk::binding(0, 1)]] ConstantBuffer Camera; +[[vk::binding(1, 1)]] ConstantBuffer Lights; +[[vk::binding(2, 1)]] ConstantBuffer Model; [[vk::push_constant]] Block PushConstant; diff --git a/samples/03_model_render/shader/model.ps.hlsl b/samples/03_model_render/shader/model.ps.hlsl index 98c850c..4c06eb6 100644 --- a/samples/03_model_render/shader/model.ps.hlsl +++ b/samples/03_model_render/shader/model.ps.hlsl @@ -70,9 +70,9 @@ float2 GetMetalRough(float2 UV) float3 SampleIrradiance(float3 Direction) { - if (PushConstant.DiffuseIrradianceHandle != INVALID_HANDLE) + if (Lights.DiffuseIrradianceHandle != INVALID_HANDLE) { - return TextureCubes[PushConstant.DiffuseIrradianceHandle].Sample(ImmutableSamplers[PushConstant.DiffuseIrradianceHandle], Direction).rgb; + return TextureCubes[Lights.DiffuseIrradianceHandle].Sample(ImmutableSamplers[Lights.DiffuseIrradianceHandle], Direction).rgb; } return 0.04f.xxx; } @@ -81,18 +81,18 @@ float3 SamplePrefiltered(float3 Direction, float Roughness) { const float MAX_MIP_LEVEL = 5.0f; float Mip = MAX_MIP_LEVEL * Roughness; - if (PushConstant.PrefilterHandle != INVALID_HANDLE) + if (Lights.PrefilterHandle != INVALID_HANDLE) { - return TextureCubes[PushConstant.PrefilterHandle].SampleLevel(ImmutableSamplers[PushConstant.PrefilterHandle], Direction, Mip).rgb; + return TextureCubes[Lights.PrefilterHandle].SampleLevel(ImmutableSamplers[Lights.PrefilterHandle], Direction, Mip).rgb; } return 0.0f.xxx; } float2 SampleBrdfLut(float NdotV, float Roughness) { - if (PushConstant.BrdfLutHandle != INVALID_HANDLE) + if (Lights.BrdfLutHandle != INVALID_HANDLE) { - return TexturesRG[PushConstant.BrdfLutHandle].Sample(ImmutableSamplers[PushConstant.BrdfLutHandle], float2(NdotV, Roughness)); + return TexturesRG[Lights.BrdfLutHandle].Sample(ImmutableSamplers[Lights.BrdfLutHandle], float2(NdotV, Roughness)); } return 0.0f.xx; } @@ -171,11 +171,11 @@ float3 GetPBRContrib(float3 Albedo, float3 LightColor, float3 ViewDir, float3 No float3 GetPointLightInfluence(float3 Albedo, float2 MetalRough, float3 Position, float3 Normal) { - if (PushConstant.LightHandle == INVALID_HANDLE) + if (Lights.LightHandle == INVALID_HANDLE) return 0.0f.xxx; - uint Offset = IndexerOffset(PushConstant.PointLightIndexer); - uint Count = IndexerCount(PushConstant.PointLightIndexer); + uint Offset = IndexerOffset(Lights.PointLightIndexer); + uint Count = IndexerCount(Lights.PointLightIndexer); float3 ViewDir = normalize(Camera.Position.xyz - Position); @@ -190,7 +190,7 @@ float3 GetPointLightInfluence(float3 Albedo, float2 MetalRough, float3 Position, float3 Contrib = 0.0f; for (uint i = 0; i < Count; ++i) { - PointLight Light = PointLightBuffer[PushConstant.LightHandle][i + Offset]; + PointLight Light = PointLightBuffer[Lights.LightHandle][i + Offset]; if (Light.Range < 0.0f) continue; @@ -218,10 +218,10 @@ float3 GetPointLightInfluence(float3 Albedo, float2 MetalRough, float3 Position, float3 GetDirectionalLightInfluence(float3 Albedo, float2 MetalRough, float3 Position, float3 Normal) { - if (PushConstant.LightHandle == INVALID_HANDLE) + if (Lights.LightHandle == INVALID_HANDLE) return 0.0f.xxx; - uint Count = IndexerCount(PushConstant.DirectionalLightIndexer); + uint Count = IndexerCount(Lights.DirectionalLightIndexer); float3 ViewDir = normalize(Camera.Position.xyz - Position); @@ -236,7 +236,7 @@ float3 GetDirectionalLightInfluence(float3 Albedo, float2 MetalRough, float3 Pos float3 Contrib = 0.0f; for (uint i = 0; i < Count; ++i) { - DirectionalLight Light = DirectionalLightBuffer[PushConstant.LightHandle][i]; + DirectionalLight Light = DirectionalLightBuffer[Lights.LightHandle][i]; if (Light.Validity_ < 0.0f) continue; @@ -279,6 +279,14 @@ float3 GetAmbientInfluence(float3 Albedo, float2 MetalRough, float3 Position, fl float3 Specular = PrefilteredColor * (K_Specular * EnvBRDF.x + EnvBRDF.y); float3 DiffuseIrradiance = Albedo * SampleIrradiance(Normal); +#ifdef _DEBUG + if ((PushConstant.DebugFlags & USE_DIFFUSE_BIT) == 0) { + DiffuseIrradiance = 0.0f.xxx; + } + if ((PushConstant.DebugFlags & USE_SPECULAR_BIT) == 0) { + Specular = 0.0f.xxx; + } +#endif return (K_Diffuse * DiffuseIrradiance + Specular) * Occlusion; }