// 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);
    }
Beispiel #3
0
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 );
}