diff --git a/Editor/EmitterWindow.cpp b/Editor/EmitterWindow.cpp index 245dd8051..259fe537e 100644 --- a/Editor/EmitterWindow.cpp +++ b/Editor/EmitterWindow.cpp @@ -172,7 +172,7 @@ EmitterWindow::EmitterWindow(EditorComponent* editor) : GUI(&editor->GetGUI()) } }); debugCheckBox->SetCheck(false); - debugCheckBox->SetTooltip("Enable debug info for the emitter. This involves reading back GPU data, so rendering can slow down."); + debugCheckBox->SetTooltip("Currently this has no functionality."); emitterWindow->AddWidget(debugCheckBox); @@ -691,18 +691,10 @@ void EmitterWindow::UpdateData() ss << "Memort Budget: " << emitter->GetMemorySizeInBytes() / 1024.0f / 1024.0f << " MB" << endl; ss << endl; - if (emitter->DEBUG) - { - auto data = emitter->GetDebugData(); - - ss << "Alive Particle Count = " << data.aliveCount << endl; - ss << "Dead Particle Count = " << data.deadCount << endl; - ss << "GPU Emit count = " << data.realEmitCount << endl; - } - else - { - ss << "For additional data, enable [DEBUG]" << endl; - } + auto data = emitter->GetStatistics(); + ss << "Alive Particle Count = " << data.aliveCount << endl; + ss << "Dead Particle Count = " << data.deadCount << endl; + ss << "GPU Emit count = " << data.realEmitCount << endl; infoLabel->SetText(ss.str()); diff --git a/WickedEngine/wiEmittedParticle.cpp b/WickedEngine/wiEmittedParticle.cpp index e8acdf012..0c49cea39 100644 --- a/WickedEngine/wiEmittedParticle.cpp +++ b/WickedEngine/wiEmittedParticle.cpp @@ -152,26 +152,12 @@ void wiEmittedParticle::CreateSelfBuffers() debugBufDesc.CPUAccessFlags = CPU_ACCESS_READ; debugBufDesc.BindFlags = 0; debugBufDesc.MiscFlags = 0; - wiRenderer::GetDevice()->CreateBuffer(&debugBufDesc, nullptr, &debugDataReadbackBuffer); + for (int i = 0; i < arraysize(statisticsReadbackBuffer); ++i) + { + wiRenderer::GetDevice()->CreateBuffer(&debugBufDesc, nullptr, &statisticsReadbackBuffer[i]); + } } - // Sorting debug buffers: - { - GPUBufferDesc debugBufDesc = aliveList[0].GetDesc(); - debugBufDesc.Usage = USAGE_STAGING; - debugBufDesc.CPUAccessFlags = CPU_ACCESS_READ; - debugBufDesc.BindFlags = 0; - debugBufDesc.MiscFlags = 0; - wiRenderer::GetDevice()->CreateBuffer(&debugBufDesc, nullptr, &debugDataReadbackIndexBuffer); - } - { - GPUBufferDesc debugBufDesc = distanceBuffer.GetDesc(); - debugBufDesc.Usage = USAGE_STAGING; - debugBufDesc.CPUAccessFlags = CPU_ACCESS_READ; - debugBufDesc.BindFlags = 0; - debugBufDesc.MiscFlags = 0; - wiRenderer::GetDevice()->CreateBuffer(&debugBufDesc, nullptr, &debugDataReadbackDistanceBuffer); - } } uint32_t wiEmittedParticle::GetMemorySizeInBytes() const @@ -215,17 +201,19 @@ void wiEmittedParticle::UpdateCPU(const TransformComponent& transform, float dt) // Swap CURRENT alivelist with NEW alivelist std::swap(aliveList[0], aliveList[1]); - if (IsDebug()) + // Read back statistics (with GPU delay): + if (statisticsReadBackIndex >= arraysize(statisticsReadbackBuffer)) { + const uint32_t oldest_stat_index = (statisticsReadBackIndex + 1) % arraysize(statisticsReadbackBuffer); GraphicsDevice* device = wiRenderer::GetDevice(); - device->WaitForGPU(); Mapping mapping; mapping._flags = Mapping::FLAG_READ; - mapping.size = sizeof(debugData); - device->Map(&debugDataReadbackBuffer, &mapping); - memcpy(&debugData, mapping.data, sizeof(debugData)); - device->Unmap(&debugDataReadbackBuffer); + mapping.size = sizeof(statistics); + device->Map(&statisticsReadbackBuffer[oldest_stat_index], &mapping); + memcpy(&statistics, mapping.data, sizeof(statistics)); + device->Unmap(&statisticsReadbackBuffer[oldest_stat_index]); } + statisticsReadBackIndex++; } void wiEmittedParticle::Burst(int num) { @@ -240,7 +228,6 @@ void wiEmittedParticle::Restart() SetPaused(false); } -//#define DEBUG_SORTING // slow but great for debug!! void wiEmittedParticle::UpdateGPU(const TransformComponent& transform, const MaterialComponent& material, const MeshComponent* mesh, CommandList cmd) const { if (!particleBuffer.IsValid()) @@ -490,71 +477,7 @@ void wiEmittedParticle::UpdateGPU(const TransformComponent& transform, const Mat if (IsSorted()) { -#ifdef DEBUG_SORTING - vector before(MAX_PARTICLES); - device->DownloadResource(&aliveList[1], &debugDataReadbackIndexBuffer, before.data()); - - ParticleCounters data; - device->DownloadResource(&counterBuffer, &debugDataReadbackBuffer, &data); - uint32_t particleCount = data.aliveCount_afterSimulation; -#endif // DEBUG_SORTING - - wiGPUSortLib::Sort(MAX_PARTICLES, distanceBuffer, counterBuffer, PARTICLECOUNTER_OFFSET_ALIVECOUNT_AFTERSIMULATION, aliveList[1], cmd); - - -#ifdef DEBUG_SORTING - vector after(MAX_PARTICLES); - device->DownloadResource(&aliveList[1], &debugDataReadbackIndexBuffer, after.data()); - - vector distances(MAX_PARTICLES); - device->DownloadResource(&distanceBuffer, &debugDataReadbackDistanceBuffer, distances.data()); - - if (particleCount > 1) - { - // CPU sort: - for (uint32_t i = 0; i < particleCount - 1; ++i) - { - for (uint32_t j = i + 1; j < particleCount; ++j) - { - uint32_t particleIndexA = before[i]; - uint32_t particleIndexB = before[j]; - - float distA = distances[particleIndexA]; - float distB = distances[particleIndexB]; - - if (distA > distB) - { - before[i] = particleIndexB; - before[j] = particleIndexA; - } - } - } - - // Validate: - bool valid = true; - uint32_t i = 0; - for (i = 0; i < particleCount; ++i) - { - if (before[i] != after[i]) - { - if (distances[before[i]] != distances[after[i]]) // if distances are equal, we just don't care... - { - valid = false; - break; - } - } - } - - assert(valid && "Invalid GPU sorting result!"); - - // Also we can reupload CPU sorted particles to verify: - if (!valid) - { - device->UpdateBuffer(&aliveList[1], before.data(), cmd); - } - } -#endif // DEBUG_SORTING } if (!IsPaused()) @@ -590,10 +513,8 @@ void wiEmittedParticle::UpdateGPU(const TransformComponent& transform, const Mat device->Barrier(barriers, arraysize(barriers), cmd); } - if (IsDebug()) - { - device->CopyResource(&debugDataReadbackBuffer, &counterBuffer, cmd); - } + // Statistics is copied to readback: + device->CopyResource(&statisticsReadbackBuffer[(statisticsReadBackIndex - 1) % arraysize(statisticsReadbackBuffer)], &counterBuffer, cmd); } diff --git a/WickedEngine/wiEmittedParticle.h b/WickedEngine/wiEmittedParticle.h index cf55c8eb7..332f65e5a 100644 --- a/WickedEngine/wiEmittedParticle.h +++ b/WickedEngine/wiEmittedParticle.h @@ -30,10 +30,8 @@ public: }; private: - ParticleCounters debugData = {}; - wiGraphics::GPUBuffer debugDataReadbackBuffer; - wiGraphics::GPUBuffer debugDataReadbackIndexBuffer; - wiGraphics::GPUBuffer debugDataReadbackDistanceBuffer; + ParticleCounters statistics = {}; + wiGraphics::GPUBuffer statisticsReadbackBuffer[wiGraphics::GraphicsDevice::GetBackBufferCount() + 1]; wiGraphics::GPUBuffer particleBuffer; wiGraphics::GPUBuffer aliveList[2]; @@ -62,7 +60,7 @@ public: void UpdateGPU(const TransformComponent& transform, const MaterialComponent& material, const MeshComponent* mesh, wiGraphics::CommandList cmd) const; void Draw(const CameraComponent& camera, const MaterialComponent& material, wiGraphics::CommandList cmd) const; - ParticleCounters GetDebugData() { return debugData; } + ParticleCounters GetStatistics() { return statistics; } enum FLAGS { @@ -113,6 +111,7 @@ public: // Non-serialized attributes: XMFLOAT3 center; + uint32_t statisticsReadBackIndex = 0; inline bool IsDebug() const { return _flags & DEBUG; } inline bool IsPaused() const { return _flags & PAUSED; } diff --git a/WickedEngine/wiGraphicsDevice.h b/WickedEngine/wiGraphicsDevice.h index fadf5e968..bb909bc7c 100644 --- a/WickedEngine/wiGraphicsDevice.h +++ b/WickedEngine/wiGraphicsDevice.h @@ -108,7 +108,7 @@ namespace wiGraphics return XMMatrixOrthographicOffCenterLH(0, (float)GetScreenWidth(), (float)GetScreenHeight(), 0, -1, 1); } inline FORMAT GetBackBufferFormat() const { return BACKBUFFER_FORMAT; } - inline static uint32_t GetBackBufferCount() { return BACKBUFFER_COUNT; } + static constexpr uint32_t GetBackBufferCount() { return BACKBUFFER_COUNT; } inline bool IsDebugDevice() const { return DEBUGDEVICE; } diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.cpp b/WickedEngine/wiGraphicsDevice_Vulkan.cpp index a6ba8abbf..bc8619a34 100644 --- a/WickedEngine/wiGraphicsDevice_Vulkan.cpp +++ b/WickedEngine/wiGraphicsDevice_Vulkan.cpp @@ -2597,6 +2597,9 @@ using namespace Vulkan_Internal; void GraphicsDevice_Vulkan::CreateBackBufferResources() { + vkQueueWaitIdle(graphicsQueue); + vkQueueWaitIdle(presentQueue); + SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice, surface); VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats); @@ -5537,7 +5540,10 @@ using namespace Vulkan_Internal; case GPU_QUERY_TYPE_TIMESTAMP: res = vkGetQueryPoolResults(device, querypool_timestamp, (uint32_t)internal_state->query_index, 1, sizeof(uint64_t), &result->result_timestamp, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT); - timestamps_to_reset.push_back((uint32_t)internal_state->query_index); + if (res == VK_SUCCESS) + { + timestamps_to_reset.push_back((uint32_t)internal_state->query_index); + } break; case GPU_QUERY_TYPE_TIMESTAMP_DISJOINT: result->result_timestamp_frequency = timestamp_frequency; @@ -5546,7 +5552,10 @@ using namespace Vulkan_Internal; case GPU_QUERY_TYPE_OCCLUSION: res = vkGetQueryPoolResults(device, querypool_occlusion, (uint32_t)internal_state->query_index, 1, sizeof(uint64_t), &result->result_passed_sample_count, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT); - occlusions_to_reset.push_back((uint32_t)internal_state->query_index); + if (res == VK_SUCCESS) + { + occlusions_to_reset.push_back((uint32_t)internal_state->query_index); + } break; } diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index ddbb473d9..557058b43 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -110,7 +110,7 @@ float deltaTime = 0; XMFLOAT2 temporalAAJitter = XMFLOAT2(0, 0); XMFLOAT2 temporalAAJitterPrev = XMFLOAT2(0, 0); float RESOLUTIONSCALE = 1.0f; -GPUQueryRing<2> occlusionQueries[256]; +GPUQueryRing occlusionQueries[256]; uint32_t entityArrayOffset_Lights = 0; uint32_t entityArrayCount_Lights = 0; uint32_t entityArrayOffset_Decals = 0; diff --git a/WickedEngine/wiScene.cpp b/WickedEngine/wiScene.cpp index 35357fcc5..f2f99036f 100644 --- a/WickedEngine/wiScene.cpp +++ b/WickedEngine/wiScene.cpp @@ -340,7 +340,7 @@ namespace wiScene { bd.StructureByteStride = sizeof(uint32_t); bd.Format = FORMAT_R32_UINT; - bd.ByteWidth = sizeof(uint32_t) * indices.size(); + bd.ByteWidth = uint32_t(sizeof(uint32_t) * indices.size()); // Use indices directly since vector is in correct format static_assert(std::is_same::value, "indices not in INDEXFORMAT_32BIT"); @@ -353,7 +353,7 @@ namespace wiScene { bd.StructureByteStride = sizeof(uint16_t); bd.Format = FORMAT_R16_UINT; - bd.ByteWidth = sizeof(uint16_t) * indices.size(); + bd.ByteWidth = uint32_t(sizeof(uint16_t) * indices.size()); std::vector gpuIndexData(indices.size()); std::copy(indices.begin(), indices.end(), gpuIndexData.begin()); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 39a689409..fd6b1de67 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates, breaking API changes const int minor = 47; // minor bug fixes, alterations, refactors, updates - const int revision = 1; + const int revision = 2; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);