Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(Draft) Bindless rendering support #62

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
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
Binary file modified Content/core/models/dev/dev_map.blend
Binary file not shown.
Binary file modified Content/core/models/dev/dev_map.blend1
Binary file not shown.
2 changes: 1 addition & 1 deletion Content/core/shaders/pbr.mshdr
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ Fragment

float ambient()
{
return 0.05;
return 0.0;
}

vec3 sampleTexture( sampler2D target )
Expand Down
2 changes: 2 additions & 0 deletions Source/Mocha.Editor/Editor/Windows/BrowserWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ private enum SortModes
public BrowserWindow()
{
CacheEverything();

isVisible = false;
}

public void SelectItem( string name )
Expand Down
2 changes: 2 additions & 0 deletions Source/Mocha.Editor/Editor/Windows/InspectorWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public class InspectorWindow : EditorWindow
public InspectorWindow()
{
Instance = this;

isVisible = false;
}

public override void Draw()
Expand Down
6 changes: 4 additions & 2 deletions Source/Mocha.Engine/BaseGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ private void TryCallMethodOnEntity( string methodName )
}
catch ( Exception ex )
{
Notify.AddError( ex.GetType().Name, ex.Message, FontAwesome.Exclamation );
var targetEx = ex.InnerException ?? ex;

Log.Error( ex );
Notify.AddError( targetEx.GetType().Name, targetEx.Message, FontAwesome.Exclamation );

Log.Error( targetEx );

FailedMethods.Add( methodHash );
}
Expand Down
2 changes: 1 addition & 1 deletion Source/Mocha.Engine/DebugOverlay.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Mocha;
namespace Mocha;

public struct DebugOverlayText
{
Expand Down
3 changes: 3 additions & 0 deletions Source/Mocha.Engine/Mocha.Engine.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@
</ItemGroup>

<ItemGroup>
<None Update="renderdoc.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Runtimes\cimgui.dll">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
Expand Down
6 changes: 3 additions & 3 deletions Source/Mocha.Engine/Render/Assets/Material.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ public Material( string path )
var shaderFileBytes = FileSystem.Mounted.ReadAllBytes( "shaders/pbr.mshdr" );
var shaderFormat = Serializer.Deserialize<MochaFile<ShaderInfo>>( shaderFileBytes );

NativeMaterial.SetShaderData(
shaderFormat.Data.VertexShaderData.ToInterop(),
shaderFormat.Data.FragmentShaderData.ToInterop()
NativeMaterial.SetShaderData(
shaderFormat.Data.VertexShaderData.ToInterop(),
shaderFormat.Data.FragmentShaderData.ToInterop()
);

NativeMaterial.Reload();
Expand Down
Binary file added Source/Mocha.Engine/renderdoc.dll
Binary file not shown.
1 change: 1 addition & 0 deletions Source/Mocha.Host/Misc/globalvars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace EngineProperties
"project.current", "Samples\\mocha-minimal\\project.json", CVarFlags::Archive, "Which project should we load?" );
BoolCVar Raytracing( "render.raytracing", true, CVarFlags::Archive, "Enable raytracing" );
BoolCVar Renderdoc( "render.renderdoc", false, CVarFlags::Archive, "Enable renderdoc" );
BoolCVar Bindless( "render.bindless", true, CVarFlags::Archive, "Enable bindless" );

StringCVar ServerName( "server.name", "Mocha Dedicated Server", CVarFlags::None, "Server name" );
StringCVar ServerPassword( "server.password", "", CVarFlags::None, "Server password" );
Expand Down
1 change: 1 addition & 0 deletions Source/Mocha.Host/Misc/globalvars.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace EngineProperties
extern StringCVar LoadedProject;
extern BoolCVar Raytracing;
extern BoolCVar Renderdoc;
extern BoolCVar Bindless;

extern StringCVar ServerHostname;
extern StringCVar ServerPassword;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,15 @@ void VulkanRenderContext::FinalizeAndCreateDevice( vkb::PhysicalDevice physicalD
deviceBuilder = deviceBuilder.add_pNext( &accelFeature ).add_pNext( &rayQueryFeature );
}

if ( EngineProperties::Bindless )
{
VkPhysicalDeviceDescriptorIndexingFeatures indexingFeatures = {};
indexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES;
indexingFeatures.pNext = nullptr;

deviceBuilder = deviceBuilder.add_pNext( &indexingFeatures );
}

vkb::Device vkbDevice = deviceBuilder.build().value();

m_device = vkbDevice.device;
Expand Down Expand Up @@ -770,6 +779,8 @@ void VulkanRenderContext::CreateSyncStructures()
// Fences are handled by VulkanCommandContexts. Our main fence is m_mainContext.fence.
}

static const uint32_t MaxBindlessResources = 16536;

void VulkanRenderContext::CreateDescriptors()
{
VkDescriptorPoolSize poolSizes[] = { { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 },
Expand All @@ -787,6 +798,16 @@ void VulkanRenderContext::CreateDescriptors()
poolInfo.pPoolSizes = poolSizes;

VK_CHECK( vkCreateDescriptorPool( m_device, &poolInfo, nullptr, &m_descriptorPool ) );

VkDescriptorPoolSize bindlessPoolSizes[] = { { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MaxBindlessResources },
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, MaxBindlessResources } };

poolInfo.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT;
poolInfo.maxSets = MaxBindlessResources * ( uint32_t )std::size( bindlessPoolSizes );
poolInfo.poolSizeCount = (uint32_t)std::size( bindlessPoolSizes );
poolInfo.pPoolSizes = bindlessPoolSizes;

VK_CHECK( vkCreateDescriptorPool( m_device, &poolInfo, nullptr, &m_bindlessDescriptorPool ) );
}

void VulkanRenderContext::CreateRenderTargets()
Expand Down Expand Up @@ -1879,13 +1900,24 @@ VulkanDescriptor::VulkanDescriptor( VulkanRenderContext* parent, DescriptorInfo_
SetParent( parent );

std::vector<VkDescriptorSetLayoutBinding> bindings = {};
bool isBindless = false;

for ( int i = 0; i < descriptorInfo.bindings.size(); ++i )
{
VkDescriptorSetLayoutBinding binding = {};
binding.binding = i;
binding.descriptorType = GetDescriptorType( descriptorInfo.bindings[i].type );
binding.descriptorCount = 1;

if (descriptorInfo.bindings[i].isBindless)
{
binding.descriptorCount = MaxBindlessResources;
isBindless = true;
}
else
{
binding.descriptorCount = 1;
}

binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_VERTEX_BIT;
binding.pImmutableSamplers = nullptr;

Expand All @@ -1894,12 +1926,51 @@ VulkanDescriptor::VulkanDescriptor( VulkanRenderContext* parent, DescriptorInfo_

VkDescriptorSetLayoutCreateInfo layoutInfo =
VKInit::DescriptorSetLayoutCreateInfo( bindings.data(), static_cast<uint32_t>( bindings.size() ) );
VK_CHECK( vkCreateDescriptorSetLayout( m_parent->m_device, &layoutInfo, nullptr, &descriptorSetLayout ) );

VkDescriptorSetAllocateInfo allocInfo =
VKInit::DescriptorSetAllocateInfo( m_parent->m_descriptorPool, &descriptorSetLayout, 1 );
if ( isBindless )
{
layoutInfo.flags |= VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT;

VkDescriptorBindingFlags bindlessFlags = VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT;
VkDescriptorSetLayoutBindingFlagsCreateInfo extendedInfo = {};
extendedInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT;
extendedInfo.pNext = nullptr;
extendedInfo.bindingCount = 1;
extendedInfo.pBindingFlags = &bindlessFlags;

VK_CHECK( vkAllocateDescriptorSets( m_parent->m_device, &allocInfo, &descriptorSet ) );
layoutInfo.pNext = &extendedInfo;

VK_CHECK( vkCreateDescriptorSetLayout( m_parent->m_device, &layoutInfo, nullptr, &descriptorSetLayout ) );
}
else
{
VK_CHECK( vkCreateDescriptorSetLayout( m_parent->m_device, &layoutInfo, nullptr, &descriptorSetLayout ) );
}

if ( isBindless )
{
VkDescriptorSetAllocateInfo allocInfo =
VKInit::DescriptorSetAllocateInfo( m_parent->m_bindlessDescriptorPool, &descriptorSetLayout, 1 );

VkDescriptorSetVariableDescriptorCountAllocateInfo countInfo = {};
countInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO;
countInfo.pNext = nullptr;

uint32_t maxBinding = MaxBindlessResources - 1;
countInfo.pDescriptorCounts = &maxBinding;
countInfo.descriptorSetCount = 1;

allocInfo.pNext = &countInfo;

VK_CHECK( vkAllocateDescriptorSets( m_parent->m_device, &allocInfo, &descriptorSet ) );
}
else
{
VkDescriptorSetAllocateInfo allocInfo =
VKInit::DescriptorSetAllocateInfo( m_parent->m_descriptorPool, &descriptorSetLayout, 1 );

VK_CHECK( vkAllocateDescriptorSets( m_parent->m_device, &allocInfo, &descriptorSet ) );
}

SetDebugName( descriptorInfo.name.c_str(), VK_OBJECT_TYPE_DESCRIPTOR_SET, ( uint64_t )descriptorSet );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ class VulkanRenderContext : public BaseRenderContext
VkSurfaceKHR m_surface;
VkSemaphore m_presentSemaphore, m_renderSemaphore;
VkDescriptorPool m_descriptorPool;
VkDescriptorPool m_bindlessDescriptorPool;

std::unique_ptr<Window> m_window;
VulkanCommandContext m_mainContext;
Expand Down Expand Up @@ -487,6 +488,12 @@ class VulkanRenderContext : public BaseRenderContext
/// </summary>
VulkanDeletionQueue m_frameDeletionQueue = {};

//
// Bindless
//
VulkanDescriptor m_bindlessDescriptor;
std::deque<VulkanImageTexture> m_bindlessTextureUpdates = {};

protected:
// ----------------------------------------

Expand Down
2 changes: 2 additions & 0 deletions Source/Mocha.Host/Rendering/baserendercontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ struct DescriptorBindingInfo_t
{
DescriptorBindingType type = DESCRIPTOR_BINDING_TYPE_IMAGE;
ImageTexture* texture = nullptr;

bool isBindless = false;
};

struct DescriptorInfo_t
Expand Down
4 changes: 2 additions & 2 deletions Source/Mocha.Host/Rendering/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Window::Window( uint32_t width, uint32_t height )
{
SDL_Init( SDL_INIT_VIDEO );

SDL_WindowFlags windowFlags = ( SDL_WindowFlags )( SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN );
SDL_WindowFlags windowFlags = ( SDL_WindowFlags )( SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_ALLOW_HIGHDPI );
m_visible = false;

std::string windowTitle = std::string( Globals::m_projectManager->GetProject().name + " [" +
Expand Down Expand Up @@ -101,7 +101,7 @@ void Window::Update()
SDL_GetWindowWMInfo( SDL_GetWindowFromID( we.windowID ), &wmi );
auto hwnd = wmi.info.win.window;

SetWindowTheme( hwnd, L"DarkMode_Explorer", NULL );
SetWindowTheme( hwnd, L"Explorer", NULL );

BOOL darkMode = 1;
if ( FAILED( DwmSetWindowAttribute( hwnd, 20, &darkMode, sizeof( darkMode ) ) ) )
Expand Down
2 changes: 1 addition & 1 deletion Source/Mocha.Hotload/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public static void Run( IntPtr args )
else
{
SetServerContext( false );

s_editor = new ProjectAssembly<IGame>( editorAssemblyInfo );
// The editor should never fail to compile.
Debug.Assert( s_editor.EntryPoint is not null );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ private static byte[] BlockCompression( byte[] data, uint width, uint height, ui
byte[] resizedData = new byte[4 * targetWidth * targetWidth];

Rgba32[] pixels = new Rgba32[width * height];
for ( int i = 0; i < pixels.Length; i ++ )
for ( int i = 0; i < pixels.Length; i++ )
{
pixels[i] = new Rgba32(
data[(i * 4) + 0],
Expand Down
Loading