ロゴ メインコンテンツへ
RSSフィード
「ソフトウェア開発」に関連する記事一覧

OpenGL GPU 処理時間の計測ユーティリティ

2016/03/02
(この記事の文字数: 105)

GL で GPU 時間を計測するためのユーティリティクラスを作ったので載せておきます。


class GpuTimer
{
public:
    GpuTimer()
        : query_back_buffer_(0)
        , query_front_buffer_(1)
    {
    }

    ~GpuTimer() throw()
    {
        DeleteAllQueries();
    }

    void Start(const char* query_id)
    {
        int query_index = GetIndex(query_id);
        if (query_index == -1)
        {
            query_index = static_cast<int>(query_ids_.size());
            AddQuery(query_id);
        }
        glBeginQuery(GL_TIME_ELAPSED, queries_[query_back_buffer_][query_index]);
    }

    void Stop()
    {
        glEndQuery(GL_TIME_ELAPSED);
    }

    void ResetAllQueries()
    {
        for (int query_index = 0, queryCount = GetQueryCount(); query_index < queryCount; ++query_index)
        {
            glBeginQuery(GL_TIME_ELAPSED, queries_[query_back_buffer_][query_index]);
            glEndQuery(GL_TIME_ELAPSED);
        }
    }

    int GetQueryCount() const
    {
        return static_cast<int>(query_ids_.size());
    }

    double GetElapsedMilliseconds(int query_index)
    {
        GLuint64 elapsed_gpu_time;
        glGetQueryObjectui64v(queries_[query_front_buffer_][query_index],
            GL_QUERY_RESULT, &elapsed_gpu_time);

        return elapsed_gpu_time / 1000000.0;
    }

    void SwapQueryBuffers()
    {
        if (query_back_buffer_ == 1)
        {
            query_back_buffer_ = 0;
            query_front_buffer_ = 1;
        }
        else
        {
            query_back_buffer_ = 1;
            query_front_buffer_ = 0;
        }
    }

    const char* GetQueryId(int query_index) const
    {
        return query_ids_[query_index].data();
    }

private:
    int GetIndex(const char* query_id) const
    {
        int query_index = 0;
        for (std::vector<std::string>::const_iterator iter = query_ids_.begin(), end = query_ids_.end();
            iter != end; ++iter, ++query_index)
        {
            const std::string* id = &*iter;
            if (*id == query_id)
            {
                return query_index;
            }
        }

        return -1;
    }

    void AddQuery(const char* query_id)
    {
        int last_index = static_cast<int>(query_ids_.size());
        query_ids_.push_back(query_id);
        queries_[query_front_buffer_].push_back(0);
        queries_[query_back_buffer_].push_back(0);
        glGenQueries(1, &queries_[query_front_buffer_][last_index]);
        glGenQueries(1, &queries_[query_back_buffer_][last_index]);
    }

    void DeleteAllQueries()
    {
        GLsizei query_count = static_cast<GLsizei>(queries_[query_front_buffer_].size());
        glDeleteQueries(query_count, queries_[query_front_buffer_].data());
        glDeleteQueries(query_count, queries_[query_back_buffer_].data());
        queries_[query_front_buffer_].clear();
        queries_[query_back_buffer_].clear();
    }

private:
    static const int QUERY_BUFFER_COUNT = 2;
    std::vector<unsigned int> queries_[QUERY_BUFFER_COUNT];
    unsigned int query_back_buffer_;
    unsigned int query_front_buffer_;
    std::vector<std::string> query_ids_;
};

class ScopedGpuTimeLogger
{
public:
    ScopedGpuTimeLogger(GpuTimer& timer, const char* query_id)
        : timer_(&timer)
    {
        timer_->Start(query_id);
    }
    ~ScopedGpuTimeLogger()
    {
        timer_->Stop();
    }

private:
    GpuTimer* timer_;
};


使用例


GpuTimer gpu_timer;

{
    ScopedGpuTimeLogger scoped_logger(gpu_timer, "GPU time 0");
    // 計測したい GPU コマンド
}

{
    ScopedGpuTimeLogger scoped_logger(gpu_timer, "GPU time 1");
    // 計測したい GPU コマンド
}

for (int query_index = 0, query_count = gpu_timer.GetQueryCount(); query_index < query_count; ++query_index)
{
    double elapsed_ms = gpu_timer.GetElapsedMilliseconds(query_index);
    printf("%s: %f ms\n", gpu_timer.GetQueryId(query_index), elapsed_ms);
}

gpu_timer.SwapQueryBuffers();

glutSwapBuffers();

参考サイト
http://www.lighthouse3d.com/tutorials/opengl-timer-query/


  このエントリーをはてなブックマークに追加  

<<「ソフトウェア開発」の記事一覧に戻る

「ソフトウェア開発」の前の記事 >>

コメント(0 件)



コンテンツロード: 0.0073 sec
Copyright(C)2006-2024 puarts All Rights Reserved