// Buffer mapping void DeviceVulkanw::MapBuffer( Buffer const* buffer, std::uint32_t queue, std::size_t offset, std::size_t size, std::uint32_t map_type, void** mapdata, Event** e ) { BufferVulkan* vulkanBuffer = ConstCast<BufferVulkan>( buffer ); // make sure GPU has stopped using this buffer WaitForFence(vulkanBuffer->m_fence_id); if( nullptr != e ) { *e = new EventVulkan(this); } // allocated a proxy buffer uint8_t* mappedMemory = new uint8_t[ size ]; (*mapdata) = mappedMemory; if ( MapType::kMapRead == map_type ) { // read the Vulkan buffer ReadBuffer( buffer, queue, offset, size, mappedMemory, e ); } else if ( MapType::kMapWrite != map_type ) { VK_EMPTY_IMPLEMENTATION; } vulkanBuffer->SetMappedMemory( mappedMemory, map_type, offset, size ); }
uint64_t DeviceVulkanw::AllocNextFenceId() { // stall if we have run out of fences to use while( m_cpu_fence_id >= m_gpu_known_fence_id + NUM_FENCE_TRACKERS) { WaitForFence(m_gpu_known_fence_id+1); } return m_cpu_fence_id.fetch_add(1); }
void CommandBufferManager::ExecuteCommandBuffer(bool submit_off_thread, bool wait_for_completion) { VkFence pending_fence = GetCurrentCommandBufferFence(); // If we're waiting for completion, don't bother waking the worker thread. PrepareToSubmitCommandBuffer(); SubmitCommandBuffer((submit_off_thread && wait_for_completion)); ActivateCommandBuffer(); if (wait_for_completion) WaitForFence(pending_fence); }
void RenderDeviceD3D12Impl::IdleGPU(bool ReleasePendingObjects) { auto FenceValue = IncrementFence(); WaitForFence(FenceValue); if(ReleasePendingObjects) { // Do not wait until the end of the frame and force deletion. // This is necessary to release outstanding references to the // swap chain buffers when it is resized in the middle of the frame. // Since GPU has been idled, it is safe to do so ProcessReleaseQueue(true); } }
void DeviceVulkanw::WriteBuffer( Buffer const* buffer, std::uint32_t queue, std::size_t offset, std::size_t size, void* src, Event** e ) { if (nullptr != e) { *e = new EventVulkan(this); } BufferVulkan* vulkanBuffer = ConstCast<BufferVulkan>( buffer ); // make sure GPU has stopped using this buffer WaitForFence(vulkanBuffer->m_fence_id); Anvil::Buffer* anvilBuffer = vulkanBuffer->GetAnvilBuffer(); anvilBuffer->write( offset, size, src ); }
/** *************************************************************************************************** * DX12CmdListProfiler::GetCmdListResults * * @brief * We assume this will be called immediately after a command list has been submitted. * * @return * A vector containing performance information for a given function. *************************************************************************************************** */ ProfilerResultCode DX12CmdListProfiler::GetCmdListResults( ID3D12GraphicsCommandList* pCmdList, ///< [in] Handle to cmd buf being measured ID3D12CommandQueue* pCmdQueue, ///< [in] Handle to cmd queue std::vector<ProfilerResult>& results) ///< [out] Vector with profiler results { DX12ProfilerCriticalSection lock(m_cs); PROFILER_ASSERT(pCmdList != nullptr); PROFILER_ASSERT(pCmdQueue != nullptr); // Signal the next fence value (with the GPU) pCmdQueue->Signal(m_pFence, m_nextFenceValue); WaitForFence(m_nextFenceValue++); ProfilerResultCode profilerResultCode = PROFILER_SUCCESS; HRESULT result = E_FAIL; if (IsCmdListBeingMeasured(pCmdList) == true) { ProfilerCmdListData& cmdListData = m_cmdListMap[pCmdList]; const UINT64 queueFrequency = GetQueueFrequency(pCmdQueue); // Loop through all measurements for this command list for (UINT i = 0; i < cmdListData.measurementGroups.size(); i++) { ProfilerMeasurementGroup& currGroup = cmdListData.measurementGroups[i]; ProfilerInterval* pTimestampData = nullptr; D3D12_QUERY_DATA_PIPELINE_STATISTICS* pPipelineStatsData = nullptr; if (m_config.measurementTypeFlags & PROFILER_MEASUREMENT_TYPE_TIMESTAMPS) { D3D12_RANGE mapRange = {}; mapRange.Begin = 0; mapRange.End = m_config.measurementsPerGroup * sizeof(ProfilerInterval); result = currGroup.pTimestampBuffer->Map(0, &mapRange, reinterpret_cast<void**>(&pTimestampData)); } if (m_config.measurementTypeFlags & PROFILER_MEASUREMENT_TYPE_PIPE_STATS) { D3D12_RANGE mapRange = {}; mapRange.Begin = 0; mapRange.End = m_config.measurementsPerGroup * sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS); result = currGroup.pPipeStatsBuffer->Map(0, &mapRange, reinterpret_cast<void**>(&pPipelineStatsData)); } // Report no results if (m_config.measurementTypeFlags == PROFILER_MEASUREMENT_TYPE_NONE) { for (UINT j = 0; j < currGroup.groupMeasurementCount; j++) { ProfilerResult profilerResult = {}; results.push_back(profilerResult); } } // Fetch our results else { for (UINT j = 0; j < currGroup.groupMeasurementCount; j++) { ProfilerResult profilerResult = {}; memcpy(&profilerResult.measurementInfo, &currGroup.measurementInfos[j], sizeof(ProfilerMeasurementInfo)); if (pTimestampData != nullptr) { UINT64* pTimerBegin = &pTimestampData[j].start; UINT64* pTimerEnd = &pTimestampData[j].end; UINT64 baseClock = pTimestampData[0].start; // Make sure the reported clock values aren't zero PROFILER_ASSERT((*pTimerBegin != 0) && (*pTimerEnd != 0)); // Store raw clocks profilerResult.timestampResult.rawClocks.start = *pTimerBegin; profilerResult.timestampResult.rawClocks.end = *pTimerEnd; // Calculate adjusted clocks profilerResult.timestampResult.adjustedClocks.start = *pTimerBegin - baseClock; profilerResult.timestampResult.adjustedClocks.end = *pTimerEnd - baseClock; // Calculate exec time profilerResult.timestampResult.execMicroSecs = static_cast<double>(*pTimerEnd - *pTimerBegin) / queueFrequency; profilerResult.timestampResult.execMicroSecs *= 1000000; } if (pPipelineStatsData != nullptr) { memcpy(&profilerResult.pipeStatsResult, pPipelineStatsData, sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS)); } results.push_back(profilerResult); } D3D12_RANGE unmapRange = {}; if (pPipelineStatsData != nullptr) { currGroup.pPipeStatsBuffer->Unmap(0, &unmapRange); } if (pTimestampData != nullptr) { currGroup.pTimestampBuffer->Unmap(0, &unmapRange); } } } // We're done profiling this command list, so free up used resources result = ReleaseProfilerData(cmdListData); PROFILER_ASSERT(result == S_OK); m_cmdListMap.erase(pCmdList); } else { profilerResultCode = PROFILER_THIS_CMD_LIST_WAS_NOT_MEASURED; } return profilerResultCode; }
void CommandQueue::WaitforIdle() { WaitForFence( m_NextFenceValue - 1 ); }