diff --git a/Editor/MeshWindow.cpp b/Editor/MeshWindow.cpp index 9410cc354..7fc41959a 100644 --- a/Editor/MeshWindow.cpp +++ b/Editor/MeshWindow.cpp @@ -557,7 +557,7 @@ void MeshWindow::Create(EditorComponent* editor) if (mesh != nullptr && morphTargetCombo.GetSelected() < (int)mesh->targets.size()) { mesh->targets[morphTargetCombo.GetSelected()].weight = args.fValue; - mesh->SetDirtyMorph(); + mesh->dirty_morph = true; } }); AddWidget(&morphTargetSlider); diff --git a/WickedEngine/RenderPath3D.cpp b/WickedEngine/RenderPath3D.cpp index e78b740b8..f96abfc8e 100644 --- a/WickedEngine/RenderPath3D.cpp +++ b/WickedEngine/RenderPath3D.cpp @@ -536,13 +536,7 @@ void RenderPath3D::Update(float dt) if (getSceneUpdateEnabled()) { - GraphicsDevice* device = wiRenderer::GetDevice(); - scene->cmd = device->BeginCommandList(); - scene->Update(dt * wiRenderer::GetGameSpeed()); - - device->StashCommandLists(); - scene->cmd = INVALID_COMMANDLIST; } // Frustum culling for main camera: diff --git a/WickedEngine/wiGraphicsDevice.h b/WickedEngine/wiGraphicsDevice.h index 364ad3d9b..118e6597c 100644 --- a/WickedEngine/wiGraphicsDevice.h +++ b/WickedEngine/wiGraphicsDevice.h @@ -69,9 +69,6 @@ namespace wiGraphics // Submit all command list that were used with BeginCommandList before this call. // This will make every command list to be in "available" state and restarts them virtual void SubmitCommandLists() = 0; - // Returns all command lists to "available" state, but doesn't submit or restart them, - // however it sets them to default pipeline state - virtual void StashCommandLists() = 0; virtual void WaitForGPU() = 0; virtual void ClearPipelineStateCache() {}; diff --git a/WickedEngine/wiGraphicsDevice_DX11.cpp b/WickedEngine/wiGraphicsDevice_DX11.cpp index 7179f72d1..8cb2b65d4 100644 --- a/WickedEngine/wiGraphicsDevice_DX11.cpp +++ b/WickedEngine/wiGraphicsDevice_DX11.cpp @@ -2708,10 +2708,6 @@ void GraphicsDevice_DX11::SubmitCommandLists() FRAMECOUNT++; } -void GraphicsDevice_DX11::StashCommandLists() -{ - cmd_count.store(0); -} void GraphicsDevice_DX11::WaitForGPU() { diff --git a/WickedEngine/wiGraphicsDevice_DX11.h b/WickedEngine/wiGraphicsDevice_DX11.h index 1258e3417..40ec6380c 100644 --- a/WickedEngine/wiGraphicsDevice_DX11.h +++ b/WickedEngine/wiGraphicsDevice_DX11.h @@ -110,7 +110,6 @@ namespace wiGraphics CommandList BeginCommandList() override; void SubmitCommandLists() override; - void StashCommandLists() override; void SetResolution(int width, int height) override; diff --git a/WickedEngine/wiGraphicsDevice_DX12.cpp b/WickedEngine/wiGraphicsDevice_DX12.cpp index 8ee5566ae..9134cba1a 100644 --- a/WickedEngine/wiGraphicsDevice_DX12.cpp +++ b/WickedEngine/wiGraphicsDevice_DX12.cpp @@ -5321,23 +5321,20 @@ using namespace DX12_Internal; descriptors[cmd].init(this); } - if (!stashed[cmd]) - { - // Start the command list in a default state: - HRESULT hr = GetFrameResources().commandAllocators[cmd]->Reset(); - assert(SUCCEEDED(hr)); - hr = GetDirectCommandList(cmd)->Reset(GetFrameResources().commandAllocators[cmd].Get(), nullptr); - assert(SUCCEEDED(hr)); + // Start the command list in a default state: + HRESULT hr = GetFrameResources().commandAllocators[cmd]->Reset(); + assert(SUCCEEDED(hr)); + hr = GetDirectCommandList(cmd)->Reset(GetFrameResources().commandAllocators[cmd].Get(), nullptr); + assert(SUCCEEDED(hr)); - ID3D12DescriptorHeap* heaps[2] = { - descriptorheap_res.heap_GPU.Get(), - descriptorheap_sam.heap_GPU.Get() - }; - GetDirectCommandList(cmd)->SetDescriptorHeaps(arraysize(heaps), heaps); + ID3D12DescriptorHeap* heaps[2] = { + descriptorheap_res.heap_GPU.Get(), + descriptorheap_sam.heap_GPU.Get() + }; + GetDirectCommandList(cmd)->SetDescriptorHeaps(arraysize(heaps), heaps); - descriptors[cmd].reset(); - GetFrameResources().resourceBuffer[cmd].clear(); - } + descriptors[cmd].reset(); + GetFrameResources().resourceBuffer[cmd].clear(); D3D12_VIEWPORT vp = {}; vp.Width = (float)RESOLUTIONWIDTH; @@ -5394,7 +5391,6 @@ using namespace DX12_Internal; cmd_count.store(0); for (CommandList cmd = 0; cmd < cmd_last; ++cmd) { - stashed[cmd] = false; query_flush(cmd); barrier_flush(cmd); @@ -5457,15 +5453,6 @@ using namespace DX12_Internal; allocationhandler->Update(FRAMECOUNT, BACKBUFFER_COUNT); } - void GraphicsDevice_DX12::StashCommandLists() - { - CommandList active_count = cmd_count.load(); - cmd_count.store(0); - for (CommandList cmd = 0; cmd < active_count; ++cmd) - { - stashed[cmd] = true; - } - } void GraphicsDevice_DX12::WaitForGPU() { diff --git a/WickedEngine/wiGraphicsDevice_DX12.h b/WickedEngine/wiGraphicsDevice_DX12.h index 97d1472e7..14e88be30 100644 --- a/WickedEngine/wiGraphicsDevice_DX12.h +++ b/WickedEngine/wiGraphicsDevice_DX12.h @@ -290,7 +290,6 @@ namespace wiGraphics std::vector query_resolves[COMMANDLIST_COUNT]; std::atomic cmd_count{ 0 }; - bool stashed[COMMANDLIST_COUNT] = {}; public: GraphicsDevice_DX12(wiPlatform::window_type window, bool fullscreen = false, bool debuglayer = false); @@ -329,7 +328,6 @@ namespace wiGraphics CommandList BeginCommandList() override; void SubmitCommandLists() override; - void StashCommandLists() override; void WaitForGPU() override; void ClearPipelineStateCache() override; diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.cpp b/WickedEngine/wiGraphicsDevice_Vulkan.cpp index c47ed9f50..40b4e063a 100644 --- a/WickedEngine/wiGraphicsDevice_Vulkan.cpp +++ b/WickedEngine/wiGraphicsDevice_Vulkan.cpp @@ -5763,25 +5763,22 @@ using namespace Vulkan_Internal; } } - if (!stashed[cmd]) - { - res = vkResetCommandPool(device, GetFrameResources().commandPools[cmd], 0); - assert(res == VK_SUCCESS); + res = vkResetCommandPool(device, GetFrameResources().commandPools[cmd], 0); + assert(res == VK_SUCCESS); - VkCommandBufferBeginInfo beginInfo = {}; - beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - beginInfo.pInheritanceInfo = nullptr; // Optional + VkCommandBufferBeginInfo beginInfo = {}; + beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + beginInfo.pInheritanceInfo = nullptr; // Optional - res = vkBeginCommandBuffer(GetFrameResources().commandBuffers[cmd], &beginInfo); - assert(res == VK_SUCCESS); + res = vkBeginCommandBuffer(GetFrameResources().commandBuffers[cmd], &beginInfo); + assert(res == VK_SUCCESS); - // reset descriptor allocators: - GetFrameResources().descriptors[cmd].reset(); + // reset descriptor allocators: + GetFrameResources().descriptors[cmd].reset(); - // reset immediate resource allocators: - GetFrameResources().resourceBuffer[cmd].clear(); - } + // reset immediate resource allocators: + GetFrameResources().resourceBuffer[cmd].clear(); Viewport viewports[6]; for (uint32_t i = 0; i < arraysize(viewports); ++i) @@ -5881,7 +5878,6 @@ using namespace Vulkan_Internal; cmd_count.store(0); for (CommandList cmd = 0; cmd < cmd_last; ++cmd) { - stashed[cmd] = false; barrier_flush(cmd); VkResult res = vkEndCommandBuffer(GetDirectCommandList(cmd)); @@ -5964,15 +5960,6 @@ using namespace Vulkan_Internal; copyQueueUse = false; copyQueueLock.unlock(); } - void GraphicsDevice_Vulkan::StashCommandLists() - { - CommandList active_count = cmd_count.load(); - cmd_count.store(0); - for (CommandList cmd = 0; cmd < active_count; ++cmd) - { - stashed[cmd] = true; - } - } void GraphicsDevice_Vulkan::WaitForGPU() { diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.h b/WickedEngine/wiGraphicsDevice_Vulkan.h index 4f5ae0ab0..883e63839 100644 --- a/WickedEngine/wiGraphicsDevice_Vulkan.h +++ b/WickedEngine/wiGraphicsDevice_Vulkan.h @@ -212,7 +212,6 @@ namespace wiGraphics void predispatch(CommandList cmd); std::atomic cmd_count{ 0 }; - bool stashed[COMMANDLIST_COUNT] = {}; std::vector common_samplers; @@ -253,7 +252,6 @@ namespace wiGraphics CommandList BeginCommandList() override; void SubmitCommandLists() override; - void StashCommandLists() override; void WaitForGPU() override; void ClearPipelineStateCache() override; diff --git a/WickedEngine/wiPhysicsEngine_Bullet.cpp b/WickedEngine/wiPhysicsEngine_Bullet.cpp index 489381128..19f35a0c0 100644 --- a/WickedEngine/wiPhysicsEngine_Bullet.cpp +++ b/WickedEngine/wiPhysicsEngine_Bullet.cpp @@ -636,16 +636,6 @@ namespace wiPhysicsEngine } } - if (scene.cmd != wiGraphics::INVALID_COMMANDLIST) - { - using namespace wiGraphics; - GraphicsDevice* device = wiRenderer::GetDevice(); - scene.cmd_locker.lock(); - device->UpdateBuffer(&mesh.streamoutBuffer_POS, physicscomponent->vertex_positions_simulation.data(), scene.cmd); - device->UpdateBuffer(&mesh.streamoutBuffer_TAN, physicscomponent->vertex_tangents_simulation.data(), scene.cmd); - scene.cmd_locker.unlock(); - } - } } } diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 64ba8ad5b..740bd122d 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -3881,6 +3881,20 @@ void UpdateRenderData( BindCommonResources(cmd); + // Update dirty material constant buffers: + for (size_t i = 0; i < vis.scene->materials.GetCount(); ++i) + { + const MaterialComponent& material = vis.scene->materials[i]; + if (material.dirty_buffer) + { + material.dirty_buffer = false; + + ShaderMaterial shadermaterial; + material.WriteShaderMaterial(&shadermaterial); + device->UpdateBuffer(&material.constantBuffer, &shadermaterial, cmd); + } + } + // Fill Entity Array with decals + envprobes + lights in the frustum: { // Reserve temporary entity array for GPU data upload: @@ -4161,6 +4175,43 @@ void UpdateRenderData( Entity entity = vis.scene->meshes.GetEntity(i); const MeshComponent& mesh = vis.scene->meshes[i]; + if (mesh.dirty_bindless && device->CheckCapability(GRAPHICSDEVICE_CAPABILITY_BINDLESS_DESCRIPTORS)) + { + mesh.dirty_bindless = false; + + ShaderMesh shadermesh; + mesh.WriteShaderMesh(&shadermesh); + + int mesh_descriptor = device->GetDescriptorIndex(&mesh.descriptor, SRV); + + size_t tmp_alloc = sizeof(ShaderMeshSubset) * mesh.subsets.size(); + ShaderMeshSubset* subsetarray = (ShaderMeshSubset*)GetRenderFrameAllocator(cmd).allocate(tmp_alloc); + int j = 0; + for (auto& x : mesh.subsets) + { + ShaderMeshSubset& shadersubset = subsetarray[j++]; + shadersubset.indexOffset = x.indexOffset; + shadersubset.indexCount = x.indexCount; + shadersubset.mesh = mesh_descriptor; + + const MaterialComponent* material = vis.scene->materials.GetComponent(x.materialID); + if (material != nullptr) + { + shadersubset.material = device->GetDescriptorIndex(&material->constantBuffer, SRV); + } + } + + device->UpdateBuffer(&mesh.descriptor, &shadermesh, cmd); + device->UpdateBuffer(&mesh.subsetBuffer, subsetarray, cmd); + GetRenderFrameAllocator(cmd).free(tmp_alloc); + } + + if (mesh.dirty_morph) + { + mesh.dirty_morph = false; + wiRenderer::GetDevice()->UpdateBuffer(&mesh.vertexBuffer_POS, mesh.vertex_positions_morphed.data(), cmd); + } + if (mesh.IsSkinned() && vis.scene->armatures.Contains(mesh.armatureID)) { const SoftBodyPhysicsComponent* softbody = vis.scene->softbodies.GetComponent(entity); @@ -4246,6 +4297,20 @@ void UpdateRenderData( device->EventEnd(cmd); wiProfiler::EndRange(range); // skinning + // Soft body updates: + for (size_t i = 0; i < vis.scene->softbodies.GetCount(); ++i) + { + Entity entity = vis.scene->softbodies.GetEntity(i); + const SoftBodyPhysicsComponent& softbody = vis.scene->softbodies[i]; + + const MeshComponent* mesh = vis.scene->meshes.GetComponent(entity); + if (mesh != nullptr) + { + device->UpdateBuffer(&mesh->streamoutBuffer_POS, softbody.vertex_positions_simulation.data(), cmd); + device->UpdateBuffer(&mesh->streamoutBuffer_TAN, softbody.vertex_tangents_simulation.data(), cmd); + } + } + // GPU Particle systems simulation/sorting/culling: if (!vis.visibleEmitters.empty()) { diff --git a/WickedEngine/wiScene.cpp b/WickedEngine/wiScene.cpp index 2f0daaf75..8f27ae4a5 100644 --- a/WickedEngine/wiScene.cpp +++ b/WickedEngine/wiScene.cpp @@ -426,7 +426,7 @@ namespace wiScene if (!targets.empty()) { vertex_positions_morphed.resize(vertex_positions.size()); - SetDirtyMorph(); + dirty_morph = true; } std::vector vertices(vertex_positions.size()); @@ -766,7 +766,7 @@ namespace wiScene if(device->CheckCapability(GRAPHICSDEVICE_CAPABILITY_BINDLESS_DESCRIPTORS)) { - _flags |= DIRTY_BINDLESS; + dirty_bindless = true; GPUBufferDesc desc; desc.BindFlags = BIND_SHADER_RESOURCE; @@ -2283,7 +2283,7 @@ namespace wiScene target_mesh->targets[j].weight = wiMath::Lerp(target_mesh->targets[j].weight, animation.morph_weights_temp[j], t); } - target_mesh->SetDirtyMorph(true); + target_mesh->dirty_morph = true; } } @@ -2597,7 +2597,7 @@ namespace wiScene if (mesh.streamoutBuffer_POS.IsValid() && mesh.vertexBuffer_PRE.IsValid()) { - mesh._flags |= MeshComponent::DIRTY_BINDLESS; + mesh.dirty_bindless = true; std::swap(mesh.streamoutBuffer_POS, mesh.vertexBuffer_PRE); } @@ -2632,7 +2632,7 @@ namespace wiScene subsetIndex++; } - if (mesh.IsDirtyMorph()) + if (mesh.dirty_morph) { mesh.BLAS_state = MeshComponent::BLAS_STATE_NEEDS_REBUILD; } @@ -2648,7 +2648,7 @@ namespace wiScene int index = device->GetDescriptorIndex(&mat->constantBuffer, SRV); if (mesh.terrain_material1_index != index) { - mesh._flags |= MeshComponent::DIRTY_BINDLESS; + mesh.dirty_bindless = true; mesh.terrain_material1_index = index; } } @@ -2661,7 +2661,7 @@ namespace wiScene int index = device->GetDescriptorIndex(&mat->constantBuffer, SRV); if (mesh.terrain_material2_index != index) { - mesh._flags |= MeshComponent::DIRTY_BINDLESS; + mesh.dirty_bindless = true; mesh.terrain_material2_index = index; } } @@ -2674,46 +2674,15 @@ namespace wiScene int index = device->GetDescriptorIndex(&mat->constantBuffer, SRV); if (mesh.terrain_material3_index != index) { - mesh._flags |= MeshComponent::DIRTY_BINDLESS; + mesh.dirty_bindless = true; mesh.terrain_material3_index = index; } } } } - if (cmd != INVALID_COMMANDLIST && device->CheckCapability(GRAPHICSDEVICE_CAPABILITY_BINDLESS_DESCRIPTORS) && mesh._flags & MeshComponent::DIRTY_BINDLESS) - { - mesh._flags &= ~MeshComponent::DIRTY_BINDLESS; - - ShaderMesh shadermesh; - mesh.WriteShaderMesh(&shadermesh); - - int mesh_descriptor = device->GetDescriptorIndex(&mesh.descriptor, SRV); - - mesh.shadersubsets.resize(mesh.subsets.size()); - int j = 0; - for (auto& x : mesh.subsets) - { - ShaderMeshSubset& shadersubset = mesh.shadersubsets[j++]; - shadersubset.indexOffset = x.indexOffset; - shadersubset.indexCount = x.indexCount; - shadersubset.mesh = mesh_descriptor; - - const MaterialComponent* material = materials.GetComponent(x.materialID); - if (material != nullptr) - { - shadersubset.material = device->GetDescriptorIndex(&material->constantBuffer, SRV); - } - } - - cmd_locker.lock(); - device->UpdateBuffer(&mesh.descriptor, &shadermesh, cmd); - device->UpdateBuffer(&mesh.subsetBuffer, mesh.shadersubsets.data(), cmd); - cmd_locker.unlock(); - } - // Update morph targets if needed: - if (cmd != INVALID_COMMANDLIST && mesh.IsDirtyMorph() && !mesh.targets.empty()) + if (mesh.dirty_morph && !mesh.targets.empty()) { XMFLOAT3 _min = XMFLOAT3(FLT_MAX, FLT_MAX, FLT_MAX); XMFLOAT3 _max = XMFLOAT3(-FLT_MAX, -FLT_MAX, -FLT_MAX); @@ -2746,11 +2715,6 @@ namespace wiScene } mesh.aabb = AABB(_min, _max); - - mesh.SetDirtyMorph(false); - cmd_locker.lock(); - wiRenderer::GetDevice()->UpdateBuffer(&mesh.vertexBuffer_POS, mesh.vertex_positions_morphed.data(), cmd); - cmd_locker.unlock(); } }); @@ -2788,14 +2752,10 @@ namespace wiScene material.engineStencilRef = STENCILREF_CUSTOMSHADER; } - if (cmd != INVALID_COMMANDLIST && material.IsDirty()) + if (material.IsDirty()) { material.SetDirty(false); - ShaderMaterial shadermaterial; - material.WriteShaderMaterial(&shadermaterial); - cmd_locker.lock(); - wiRenderer::GetDevice()->UpdateBuffer(&material.constantBuffer, &shadermaterial, cmd); - cmd_locker.unlock(); + material.dirty_buffer = true; } }); diff --git a/WickedEngine/wiScene.h b/WickedEngine/wiScene.h index 422818649..6c29a298b 100644 --- a/WickedEngine/wiScene.h +++ b/WickedEngine/wiScene.h @@ -221,6 +221,7 @@ namespace wiScene // Non-serialized attributes: wiGraphics::GPUBuffer constantBuffer; uint32_t layerMask = ~0u; + mutable bool dirty_buffer = false; // User stencil value can be in range [0, 15] inline void SetUserStencilRef(uint8_t value) @@ -315,8 +316,8 @@ namespace wiScene DOUBLE_SIDED = 1 << 1, DYNAMIC = 1 << 2, TERRAIN = 1 << 3, - DIRTY_MORPH = 1 << 4, - DIRTY_BINDLESS = 1 << 5, + _DEPRECATED_DIRTY_MORPH = 1 << 4, + _DEPRECATED_DIRTY_BINDLESS = 1 << 5, }; uint32_t _flags = RENDERABLE; @@ -393,19 +394,18 @@ namespace wiScene int terrain_material2_index = -1; int terrain_material3_index = -1; - std::vector shadersubsets; + mutable bool dirty_morph = false; + mutable bool dirty_bindless = true; inline void SetRenderable(bool value) { if (value) { _flags |= RENDERABLE; } else { _flags &= ~RENDERABLE; } } inline void SetDoubleSided(bool value) { if (value) { _flags |= DOUBLE_SIDED; } else { _flags &= ~DOUBLE_SIDED; } } inline void SetDynamic(bool value) { if (value) { _flags |= DYNAMIC; } else { _flags &= ~DYNAMIC; } } inline void SetTerrain(bool value) { if (value) { _flags |= TERRAIN; } else { _flags &= ~TERRAIN; } } - inline void SetDirtyMorph(bool value = true) { if (value) { _flags |= DIRTY_MORPH; } else { _flags &= ~DIRTY_MORPH; } } - + inline bool IsRenderable() const { return _flags & RENDERABLE; } inline bool IsDoubleSided() const { return _flags & DOUBLE_SIDED; } inline bool IsDynamic() const { return _flags & DYNAMIC; } inline bool IsTerrain() const { return _flags & TERRAIN; } - inline bool IsDirtyMorph() const { return _flags & DIRTY_MORPH; } inline float GetTessellationFactor() const { return tessellationFactor; } inline wiGraphics::INDEXBUFFER_FORMAT GetIndexFormat() const { return vertex_positions.size() > 65535 ? wiGraphics::INDEXFORMAT_32BIT : wiGraphics::INDEXFORMAT_16BIT; } @@ -1302,9 +1302,6 @@ namespace wiScene mutable bool BVH_invalid = false; void InvalidateBVH() { BVH_invalid = true; } - std::mutex cmd_locker; - wiGraphics::CommandList cmd = wiGraphics::INVALID_COMMANDLIST; // for gpu data updates - wiGraphics::GPUQueryHeap queryHeap[arraysize(ObjectComponent::occlusionQueries)]; std::vector queryResults; uint32_t writtenQueries[arraysize(queryHeap)] = {}; diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index f2ba28351..9985bc2c3 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates, breaking compatibility changes const int minor = 55; // minor bug fixes, alterations, refactors, updates - const int revision = 13; + const int revision = 14; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);