Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
**/*.lib filter=lfs diff=lfs merge=lfs -text
**/*.pdb filter=lfs diff=lfs merge=lfs -text
**/*.so filter=lfs diff=lfs merge=lfs -text
**/linux-x64/** filter=lfs diff=lfs merge=lfs -text
**/linux-x64/** filter=lfs diff=lfs merge=lfs -text
resources/texture/*.jpg filter=lfs diff=lfs merge=lfs -text
3 changes: 3 additions & 0 deletions resources/texture/grid.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/texture/sample.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 1 addition & 5 deletions src/Graphics/Instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,7 @@ Instance::Instance(App* app) :
#endif

// Instance Creation
#ifdef VK_API_VERSION_1_1
m_ApiVersion = m_Context.enumerateInstanceVersion(); // TODO: potential crash
#else
m_ApiVersion = VK_API_VERSION_1_0;
#endif
m_ApiVersion = VK_API_VERSION_1_3;

std::vector<const char*> enabledInstanceExtensions = BuildEnabledExtensions<VulkanInstanceExtensionBitset, VulkanInstanceExtension>(instanceExtensionProperties,
m_EnabledInstanceExtensions);
Expand Down
9 changes: 9 additions & 0 deletions src/Rendering/BindGroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ struct TextureBinding final
SamplerHandle samplerHandle = {};
};

/// @brief Texture binding for bindless textures
struct ArrayTexturesBinding final
{
uint32_t binding = 0;
uint32_t count = 0;
std::vector<TextureHandle> handles = {};
TextureUsageBits usage = TextureUsageBits::Sampled;
};

/// @brief Buffer handle with byte offset
struct BufferBinding final
{
Expand Down
2 changes: 1 addition & 1 deletion src/Rendering/BindLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct Binding final
{
uint8_t binding = 0;
BindType type = BindType::UniformBuffer;
uint8_t descriptorCount = 1;
uint16_t descriptorCount = 1;
ShaderStage stage = ShaderStage::Vertex;
};

Expand Down
12 changes: 10 additions & 2 deletions src/Rendering/GraphicsCaps.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
#include "GraphicsCaps.h"
#include "Graphics/Graphics.h"

namespace gore::gfx
{
void InitVulkanGraphicsCaps(GraphicsCaps& caps, vk::Instance instance, vk::PhysicalDevice physicalDevice)
void InitVulkanGraphicsCaps(GraphicsCaps& caps, Instance& instance, Device& device)
{
vk::PhysicalDeviceProperties deviceProperties = physicalDevice.getProperties();
uint32_t vulkanMinorVersion = VK_API_VERSION_MINOR(instance.Version());

vk::PhysicalDeviceProperties deviceProperties = device.GetPhysicalDevice().Get().getProperties();
caps.minUniformBufferOffsetAlignment = deviceProperties.limits.minUniformBufferOffsetAlignment;

// Check for bindless support, which is available in Vulkan 1.2 and later
// Note: This is a simplified check. In a real application, you would want to check for specific features
// but if the device cannot support vulkan 1.2, it cannot support bindless.
caps.supportsBindless = vulkanMinorVersion >= 2;
}
} // namespace gore::gfx
7 changes: 6 additions & 1 deletion src/Rendering/GraphicsCaps.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@

namespace gore::gfx
{
class Instance;
class Device;

struct GraphicsCaps
{
size_t minUniformBufferOffsetAlignment = 0;

bool supportsBindless = false;
};

void InitVulkanGraphicsCaps(GraphicsCaps& caps, vk::Instance instance, vk::PhysicalDevice physicalDevice);
void InitVulkanGraphicsCaps(GraphicsCaps& caps, Instance& instance, Device& device);
} // namespace gore::gfx
23 changes: 21 additions & 2 deletions src/Rendering/RenderContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ BindLayout RenderContext::GetOrCreateBindLayout(const BindLayoutCreateInfo& crea
return it->second;
}

BindLayout bindLayout;
bool isBindless = false;

std::vector<vk::DescriptorSetLayoutBinding> bindings;
std::vector<vk::DescriptorBindingFlags> bindingFlags;
for (const auto& binding : createInfo.bindings)
{
vk::DescriptorSetLayoutBinding layoutBinding(
Expand All @@ -76,9 +78,26 @@ BindLayout RenderContext::GetOrCreateBindLayout(const BindLayoutCreateInfo& crea
nullptr);

bindings.push_back(layoutBinding);

isBindless |= (binding.descriptorCount > 1);
bindingFlags.push_back(binding.descriptorCount > 1 ? vk::DescriptorBindingFlagBits::ePartiallyBound : vk::DescriptorBindingFlags());
}

auto layoutCreateInfo = vk::DescriptorSetLayoutCreateInfo()
.setBindingCount(static_cast<uint32_t>(bindings.size()))
.setPBindings(bindings.data());

auto layoutBindingCreateFlagsInfo = vk::DescriptorSetLayoutBindingFlagsCreateInfo()
.setBindingCount(static_cast<uint32_t>(bindingFlags.size()))
.setPBindingFlags(bindingFlags.data());

bindLayout.layout = VULKAN_DEVICE.createDescriptorSetLayout({{}, static_cast<uint32_t>(bindings.size()), bindings.data()});
if (isBindless)
{
layoutCreateInfo.setPNext(&layoutBindingCreateFlagsInfo);
}

BindLayout bindLayout;
bindLayout.layout = VULKAN_DEVICE.createDescriptorSetLayout(layoutCreateInfo);

SetObjectDebugName(bindLayout.layout, createInfo.name != nullptr ? createInfo.name : "NoName_BindLayout");

Expand Down
53 changes: 45 additions & 8 deletions src/Rendering/RenderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ void RenderSystem::Initialize()
m_Swapchain = m_Device.CreateSwapchain(window->GetNativeHandle(), swapchainCount, static_cast<uint32_t>(width), static_cast<uint32_t>(height));
m_Device.SetName(m_Swapchain.Get(), "Main Swapchain");

InitVulkanGraphicsCaps(m_GraphicsCaps, *m_Instance.Get(), *m_Device.GetPhysicalDevice().Get());
InitVulkanGraphicsCaps(m_GraphicsCaps, m_Instance, m_Device);

RenderContextCreateInfo renderContextCreateInfo = {};
renderContextCreateInfo.device = &m_Device;
Expand Down Expand Up @@ -148,6 +148,7 @@ void RenderSystem::Initialize()
CreateTextureObjects();

CreateGlobalDescriptorSets();
CreateMaterialDescriptorSets();
CreateShadowPassObject();
CreateUVQuadDescriptorSets();
CreateDynamicUniformBuffer();
Expand Down Expand Up @@ -1184,6 +1185,39 @@ void RenderSystem::CreateGlobalDescriptorSets()
});
}

void RenderSystem::CreateMaterialDescriptorSets()
{
std::vector<Binding> bindings {
{0, BindType::SampledImage, 256, ShaderStage::Fragment},
{1, BindType::Sampler, 1, ShaderStage::Fragment}
};

BindLayoutCreateInfo bindLayoutCreateInfo =
{
.name = "Bindless Material Descriptor Set Layout",
.bindings = bindings
};

m_BindlessMaterialBinding.bindLayout = m_RenderContext->GetOrCreateBindLayout(bindLayoutCreateInfo);

m_BindlessMaterialBinding.albedoSampler = m_RenderContext->CreateSampler({
.debugName = "Bindless Material Sampler"
});

m_BindlessMaterialBinding.bindGroup = m_RenderContext->CreateBindGroup({
.debugName = "Bindless Material BindGroup",
.updateFrequency = UpdateFrequency::Persistent,
.textures = {
{0, m_DefaultResources.whiteTexture, TextureUsageBits::Sampled, 0},
{0, m_DefaultResources.blackTexture, TextureUsageBits::Sampled, 1},
{0, m_DefaultResources.gridTexture, TextureUsageBits::Sampled, 2},
{0, m_UVCheckTextureHandle, TextureUsageBits::Sampled, 3}},
.buffers = {},
.samplers = {{1, m_BindlessMaterialBinding.albedoSampler}},
.bindLayout = &m_BindlessMaterialBinding.bindLayout,
});
}

void RenderSystem:: CreateUVQuadDescriptorSets()
{
std::vector<Binding> bindings {
Expand Down Expand Up @@ -1551,7 +1585,7 @@ void RenderSystem::CreateRpsPipelines()
{.byteOffset = 0, .format = GraphicsFormat::RGB32_FLOAT},
{.byteOffset = 12, .format = GraphicsFormat::RG32_FLOAT},
{.byteOffset = 20, .format = GraphicsFormat::RGB32_FLOAT}}}},
.bindLayouts = { m_GlobalBindLayout, m_ShadowPassBindLayout },
.bindLayouts = { m_GlobalBindLayout, m_ShadowPassBindLayout, m_BindlessMaterialBinding.bindLayout },
.dynamicBuffer = m_DynamicBufferHandle,
.renderPass = forwardPass.GetRenderPass().renderPass,
.subpassIndex = 0
Expand Down Expand Up @@ -1601,11 +1635,13 @@ void RenderSystem::CreateRpsPipelines()
.bindGroup = {m_GlobalBindGroup},
});

forwardMat.AddPass(Pass{
.name = "ForwardPass",
.shader = m_RpsPipelines.forwardPipeline,
.bindGroup = {m_GlobalBindGroup},
});
Pass forwardOpaquePass;
forwardOpaquePass.name = "ForwardPass";
forwardOpaquePass.shader = m_RpsPipelines.forwardPipeline;
forwardOpaquePass.bindGroup[0] = m_GlobalBindGroup;
forwardOpaquePass.bindGroup[2] = m_BindlessMaterialBinding.bindGroup;

forwardMat.AddPass(forwardOpaquePass);
}

void RenderSystem::CreateDefaultResources()
Expand All @@ -1632,6 +1668,8 @@ void RenderSystem::CreateDefaultResources()
.data = whiteTextureData.data(),
.dataSize = 4,
});

m_DefaultResources.gridTexture = m_RenderContext->CreateTextureHandle("grid.jpg");
}

void RenderSystem::UpdateGlobalConstantBuffer()
Expand Down Expand Up @@ -1718,4 +1756,3 @@ void RenderSystem::ResetPerFrameDescriptorPool()
m_RenderContext->ResetDescriptorPool(UpdateFrequency::PerFrame);
}
} // namespace gore

11 changes: 11 additions & 0 deletions src/Rendering/RenderSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ ENGINE_CLASS(RenderSystem) final : System
{
TextureHandle whiteTexture;
TextureHandle blackTexture;
TextureHandle gridTexture;
} m_DefaultResources;

void CreateDefaultResources();
Expand Down Expand Up @@ -241,6 +242,15 @@ ENGINE_CLASS(RenderSystem) final : System
BindGroupHandle m_GlobalBindGroup;
BufferHandle m_GlobalConstantBuffer;

// Material Binding
struct MaterialBinding
{
SamplerHandle albedoSampler;

BindLayout bindLayout;
BindGroupHandle bindGroup;
} m_BindlessMaterialBinding;

// Pass Binding
BindLayout m_ShadowPassBindLayout;
SamplerHandle m_ShadowmapSamplerHandler;
Expand Down Expand Up @@ -276,6 +286,7 @@ ENGINE_CLASS(RenderSystem) final : System
void CreateSwapchain(uint32_t imageCount, uint32_t width, uint32_t height);
void CreateDepthBuffer();
void CreateGlobalDescriptorSets();
void CreateMaterialDescriptorSets();
void CreateShadowPassObject();
void CreateUVQuadDescriptorSets();
void CreateDynamicUniformBuffer();
Expand Down
8 changes: 8 additions & 0 deletions src/Shaders/ShaderLibrary/BindlessMaterial.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once
#include "Core/Common.hlsl"


ARRAY_TEXTURES(MATERIAL, 0, _Albedo, float4);
SAMPLER(MATERIAL, 1, _AlbedoSampler);
// ARRAY_TEXTURES(MATERIAL, 1, _Normal, float4);
// ARRAY_TEXTURES(MATERIAL, 2, _Mask, float4);
1 change: 1 addition & 0 deletions src/Shaders/ShaderLibrary/Core/Common.hlsl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// WORKAROUND: would add api macro to shader compiler in the future
#define VULKAN_API (1)
#define SUPPORT_BINDLESS (1)

#ifndef GORE_COMMON
#define GORE_COMMON
Expand Down
1 change: 0 additions & 1 deletion src/Shaders/ShaderLibrary/Core/Shadow.hlsl

This file was deleted.

1 change: 1 addition & 0 deletions src/Shaders/ShaderLibrary/Core/VulkanBinding.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ COMBINED_IMAGE_SAMPLER DESCRIPTOR_SET_BINDING(Binding, Region##_BINDING_DESCRIPT

#define SAMPLER(Region, Binding, SamplerName) DESCRIPTOR_SET_BINDING(Binding, Region##_BINDING_DESCRIPTOR_SET) HLSL_SAMPLER(SamplerName)

#define ARRAY_TEXTURES(Region, Binding, ArrayTextureName, Format) DESCRIPTOR_SET_BINDING(Binding, Region##_BINDING_DESCRIPTOR_SET) HLSL_ARRAY_TEXTURES(ArrayTextureName, Format)
#endif
8 changes: 8 additions & 0 deletions src/Shaders/ShaderLibrary/Core/VulkanVariables.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,12 @@
#define SAMPLE_TEXTURE_2D(TextureName, UV) TextureName.Sample(TextureName##Sampler, UV)
#define SAMPLE_TEXTURE_2D_SAMPLER(TextureName, SamplerName, UV) TextureName.Sample(SamplerName, UV)

#if SUPPORT_BINDLESS
#define HLSL_ARRAY_TEXTURES(ArrayTextureName, Format) Texture2D<Format> ArrayTextureName[]
#define LOAD_ARRAY_TEXTURES(ArrayTextureName, Index) ArrayTextureName[Index]
#else
#define HLSL_ARRAY_TEXTURES(ArrayTextureName, Format) Texture2D<Format> ArrayTextureName
#define LOAD_ARRAY_TEXTURES(ArrayTextureName, Index) ArrayTextureName
#endif

#endif
6 changes: 4 additions & 2 deletions src/Shaders/sample/SimpleLit.hlsl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "../ShaderLibrary/GlobalBinding.hlsl"
#include "../ShaderLibrary/ShadowPassBinding.hlsl"
#include "../ShaderLibrary/BindlessMaterial.hlsl"

struct Attributes
{
Expand Down Expand Up @@ -48,6 +49,7 @@ float4 ps(Varyings v) : SV_Target0
float shadowMapDepth = _DirectionalShadowmap.Sample(_DirectionalShadowmapSampler, shadowCoord.xy).r;
float shadowFactor = shadowCoord.z < shadowMapDepth ? 1.0f : 0.0f;

// Return the shadow factor as the output color
return float4(shadowFactor, shadowFactor, shadowFactor, 1.0f);
Texture2D albedo = LOAD_ARRAY_TEXTURES(_Albedo, 3);

return albedo.Sample(_AlbedoSampler, uv);
}
Loading