diff --git a/Content/core/models/dev/dev_map.blend b/Content/core/models/dev/dev_map.blend index b11ce519..236216f0 100644 Binary files a/Content/core/models/dev/dev_map.blend and b/Content/core/models/dev/dev_map.blend differ diff --git a/Content/core/models/dev/dev_map.blend1 b/Content/core/models/dev/dev_map.blend1 index ed2827ca..b11ce519 100644 Binary files a/Content/core/models/dev/dev_map.blend1 and b/Content/core/models/dev/dev_map.blend1 differ diff --git a/Content/core/shaders/pbr.mshdr b/Content/core/shaders/pbr.mshdr index 8b9eeccb..e7d19cef 100644 --- a/Content/core/shaders/pbr.mshdr +++ b/Content/core/shaders/pbr.mshdr @@ -188,7 +188,7 @@ Fragment float ambient() { - return 0.05; + return 0.0; } vec3 sampleTexture( sampler2D target ) diff --git a/Source/Mocha.Editor/Editor/Windows/BrowserWindow.cs b/Source/Mocha.Editor/Editor/Windows/BrowserWindow.cs index eb9b9463..c7467884 100644 --- a/Source/Mocha.Editor/Editor/Windows/BrowserWindow.cs +++ b/Source/Mocha.Editor/Editor/Windows/BrowserWindow.cs @@ -24,6 +24,8 @@ private enum SortModes public BrowserWindow() { CacheEverything(); + + isVisible = false; } public void SelectItem( string name ) diff --git a/Source/Mocha.Editor/Editor/Windows/InspectorWindow.cs b/Source/Mocha.Editor/Editor/Windows/InspectorWindow.cs index e61bdf18..95023fce 100644 --- a/Source/Mocha.Editor/Editor/Windows/InspectorWindow.cs +++ b/Source/Mocha.Editor/Editor/Windows/InspectorWindow.cs @@ -14,6 +14,8 @@ public class InspectorWindow : EditorWindow public InspectorWindow() { Instance = this; + + isVisible = false; } public override void Draw() diff --git a/Source/Mocha.Engine/BaseGame.cs b/Source/Mocha.Engine/BaseGame.cs index 6c719c99..8bffbcc1 100644 --- a/Source/Mocha.Engine/BaseGame.cs +++ b/Source/Mocha.Engine/BaseGame.cs @@ -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 ); } diff --git a/Source/Mocha.Engine/DebugOverlay.cs b/Source/Mocha.Engine/DebugOverlay.cs index dd71f57e..eef0e9f7 100644 --- a/Source/Mocha.Engine/DebugOverlay.cs +++ b/Source/Mocha.Engine/DebugOverlay.cs @@ -1,4 +1,4 @@ -namespace Mocha; +namespace Mocha; public struct DebugOverlayText { diff --git a/Source/Mocha.Engine/Mocha.Engine.csproj b/Source/Mocha.Engine/Mocha.Engine.csproj index 9692d00b..bf9bf75b 100644 --- a/Source/Mocha.Engine/Mocha.Engine.csproj +++ b/Source/Mocha.Engine/Mocha.Engine.csproj @@ -59,6 +59,9 @@ + + PreserveNewest + Never diff --git a/Source/Mocha.Engine/Render/Assets/Material.cs b/Source/Mocha.Engine/Render/Assets/Material.cs index b52f676d..c434187d 100644 --- a/Source/Mocha.Engine/Render/Assets/Material.cs +++ b/Source/Mocha.Engine/Render/Assets/Material.cs @@ -82,9 +82,9 @@ public Material( string path ) var shaderFileBytes = FileSystem.Mounted.ReadAllBytes( "shaders/pbr.mshdr" ); var shaderFormat = Serializer.Deserialize>( shaderFileBytes ); - NativeMaterial.SetShaderData( - shaderFormat.Data.VertexShaderData.ToInterop(), - shaderFormat.Data.FragmentShaderData.ToInterop() + NativeMaterial.SetShaderData( + shaderFormat.Data.VertexShaderData.ToInterop(), + shaderFormat.Data.FragmentShaderData.ToInterop() ); NativeMaterial.Reload(); diff --git a/Source/Mocha.Engine/renderdoc.dll b/Source/Mocha.Engine/renderdoc.dll new file mode 100644 index 00000000..aa0cd46a Binary files /dev/null and b/Source/Mocha.Engine/renderdoc.dll differ diff --git a/Source/Mocha.Host/Misc/globalvars.cpp b/Source/Mocha.Host/Misc/globalvars.cpp index 4c329263..d0f812c5 100644 --- a/Source/Mocha.Host/Misc/globalvars.cpp +++ b/Source/Mocha.Host/Misc/globalvars.cpp @@ -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" ); diff --git a/Source/Mocha.Host/Misc/globalvars.h b/Source/Mocha.Host/Misc/globalvars.h index 163cca2f..a213bafe 100644 --- a/Source/Mocha.Host/Misc/globalvars.h +++ b/Source/Mocha.Host/Misc/globalvars.h @@ -14,6 +14,7 @@ namespace EngineProperties extern StringCVar LoadedProject; extern BoolCVar Raytracing; extern BoolCVar Renderdoc; + extern BoolCVar Bindless; extern StringCVar ServerHostname; extern StringCVar ServerPassword; diff --git a/Source/Mocha.Host/Rendering/Platform/Vulkan/vulkanrendercontext.cpp b/Source/Mocha.Host/Rendering/Platform/Vulkan/vulkanrendercontext.cpp index 9ecddafe..fc9be7be 100644 --- a/Source/Mocha.Host/Rendering/Platform/Vulkan/vulkanrendercontext.cpp +++ b/Source/Mocha.Host/Rendering/Platform/Vulkan/vulkanrendercontext.cpp @@ -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; @@ -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 }, @@ -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() @@ -1879,13 +1900,24 @@ VulkanDescriptor::VulkanDescriptor( VulkanRenderContext* parent, DescriptorInfo_ SetParent( parent ); std::vector 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; @@ -1894,12 +1926,51 @@ VulkanDescriptor::VulkanDescriptor( VulkanRenderContext* parent, DescriptorInfo_ VkDescriptorSetLayoutCreateInfo layoutInfo = VKInit::DescriptorSetLayoutCreateInfo( bindings.data(), static_cast( 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 ); diff --git a/Source/Mocha.Host/Rendering/Platform/Vulkan/vulkanrendercontext.h b/Source/Mocha.Host/Rendering/Platform/Vulkan/vulkanrendercontext.h index 356f55c6..50fe0120 100644 --- a/Source/Mocha.Host/Rendering/Platform/Vulkan/vulkanrendercontext.h +++ b/Source/Mocha.Host/Rendering/Platform/Vulkan/vulkanrendercontext.h @@ -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 m_window; VulkanCommandContext m_mainContext; @@ -487,6 +488,12 @@ class VulkanRenderContext : public BaseRenderContext /// VulkanDeletionQueue m_frameDeletionQueue = {}; + // + // Bindless + // + VulkanDescriptor m_bindlessDescriptor; + std::deque m_bindlessTextureUpdates = {}; + protected: // ---------------------------------------- diff --git a/Source/Mocha.Host/Rendering/baserendercontext.h b/Source/Mocha.Host/Rendering/baserendercontext.h index 477ceac7..9c83a28b 100644 --- a/Source/Mocha.Host/Rendering/baserendercontext.h +++ b/Source/Mocha.Host/Rendering/baserendercontext.h @@ -146,6 +146,8 @@ struct DescriptorBindingInfo_t { DescriptorBindingType type = DESCRIPTOR_BINDING_TYPE_IMAGE; ImageTexture* texture = nullptr; + + bool isBindless = false; }; struct DescriptorInfo_t diff --git a/Source/Mocha.Host/Rendering/window.cpp b/Source/Mocha.Host/Rendering/window.cpp index 1a8e5e87..f1daf210 100644 --- a/Source/Mocha.Host/Rendering/window.cpp +++ b/Source/Mocha.Host/Rendering/window.cpp @@ -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 + " [" + @@ -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 ) ) ) ) diff --git a/Source/Mocha.Hotload/Main.cs b/Source/Mocha.Hotload/Main.cs index b87fb107..f1fdc6b8 100644 --- a/Source/Mocha.Hotload/Main.cs +++ b/Source/Mocha.Hotload/Main.cs @@ -142,7 +142,7 @@ public static void Run( IntPtr args ) else { SetServerContext( false ); - + s_editor = new ProjectAssembly( editorAssemblyInfo ); // The editor should never fail to compile. Debug.Assert( s_editor.EntryPoint is not null ); diff --git a/Source/MochaTool.AssetCompiler/Handlers/Texture/TextureCompiler.cs b/Source/MochaTool.AssetCompiler/Handlers/Texture/TextureCompiler.cs index c3559781..5816aa6a 100644 --- a/Source/MochaTool.AssetCompiler/Handlers/Texture/TextureCompiler.cs +++ b/Source/MochaTool.AssetCompiler/Handlers/Texture/TextureCompiler.cs @@ -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],