blob: c3214025bfa6572c1a78845bf3df49bfdfd660a2 [file] [log] [blame]
Jamie Madill9e54b5a2016-05-25 12:57:39 -04001//
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -04002// Copyright 2016-2018 The ANGLE Project Authors. All rights reserved.
Jamie Madill9e54b5a2016-05-25 12:57:39 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6// QueryVk.cpp:
7// Implements the class methods for QueryVk.
8//
9
10#include "libANGLE/renderer/vulkan/QueryVk.h"
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040011#include "libANGLE/Context.h"
12#include "libANGLE/renderer/vulkan/ContextVk.h"
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -040013#include "libANGLE/renderer/vulkan/RendererVk.h"
Jamie Madill9e54b5a2016-05-25 12:57:39 -040014
15#include "common/debug.h"
16
17namespace rx
18{
19
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040020QueryVk::QueryVk(gl::QueryType type) : QueryImpl(type), mCachedResult(0), mCachedResultValid(false)
Jamie Madillb980c562018-11-27 11:34:27 -050021{}
Jamie Madill9e54b5a2016-05-25 12:57:39 -040022
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040023QueryVk::~QueryVk() = default;
24
Jamie Madillf4a789f2018-10-18 16:56:20 -040025void QueryVk::onDestroy(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040026{
Jamie Madille4634a12018-11-14 09:54:35 -050027 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madillf4a789f2018-10-18 16:56:20 -040028 vk::DynamicQueryPool *queryPool = contextVk->getQueryPool(getType());
29 queryPool->freeQuery(contextVk, &mQueryHelper);
30 queryPool->freeQuery(contextVk, &mQueryHelperTimeElapsedBegin);
Jamie Madill9e54b5a2016-05-25 12:57:39 -040031}
32
Jamie Madillf4a789f2018-10-18 16:56:20 -040033angle::Result QueryVk::begin(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040034{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040035 ContextVk *contextVk = vk::GetImpl(context);
36
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040037 mCachedResultValid = false;
38
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -040039 if (!mQueryHelper.getQueryPool())
40 {
41 ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(contextVk, &mQueryHelper));
42 }
43
44 // Note: TimeElapsed is implemented by using two Timestamp queries and taking the diff.
45 if (getType() == gl::QueryType::TimeElapsed)
46 {
47 if (!mQueryHelperTimeElapsedBegin.getQueryPool())
48 {
49 ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(
50 contextVk, &mQueryHelperTimeElapsedBegin));
51 }
52
Shahbaz Youssefic81e7bf2019-01-18 15:35:55 -050053 mQueryHelperTimeElapsedBegin.writeTimestamp(contextVk);
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -040054 }
55 else
56 {
Shahbaz Youssefic81e7bf2019-01-18 15:35:55 -050057 mQueryHelper.beginQuery(contextVk);
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -040058 }
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040059
Jamie Madill7c985f52018-11-29 18:16:17 -050060 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -040061}
62
Jamie Madillf4a789f2018-10-18 16:56:20 -040063angle::Result QueryVk::end(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040064{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040065 ContextVk *contextVk = vk::GetImpl(context);
66
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -040067 if (getType() == gl::QueryType::TimeElapsed)
68 {
Shahbaz Youssefic81e7bf2019-01-18 15:35:55 -050069 mQueryHelper.writeTimestamp(contextVk);
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -040070 }
71 else
72 {
Shahbaz Youssefic81e7bf2019-01-18 15:35:55 -050073 mQueryHelper.endQuery(contextVk);
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -040074 }
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040075
Jamie Madill7c985f52018-11-29 18:16:17 -050076 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -040077}
78
Jamie Madillf4a789f2018-10-18 16:56:20 -040079angle::Result QueryVk::queryCounter(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040080{
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -040081 ContextVk *contextVk = vk::GetImpl(context);
82
83 mCachedResultValid = false;
84
85 if (!mQueryHelper.getQueryPool())
86 {
87 ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(contextVk, &mQueryHelper));
88 }
89
90 ASSERT(getType() == gl::QueryType::Timestamp);
91
Shahbaz Youssefic81e7bf2019-01-18 15:35:55 -050092 mQueryHelper.writeTimestamp(contextVk);
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -040093
Jamie Madill7c985f52018-11-29 18:16:17 -050094 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -040095}
96
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040097angle::Result QueryVk::getResult(const gl::Context *context, bool wait)
98{
99 if (mCachedResultValid)
100 {
Jamie Madill7c985f52018-11-29 18:16:17 -0500101 return angle::Result::Continue;
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400102 }
103
104 ContextVk *contextVk = vk::GetImpl(context);
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400105 RendererVk *renderer = contextVk->getRenderer();
106
107 // glGetQueryObject* requires an implicit flush of the command buffers to guarantee execution in
108 // finite time.
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -0400109 // Note regarding time-elapsed: end should have been called after begin, so flushing when end
110 // has pending work should flush begin too.
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400111 if (mQueryHelper.hasPendingWork(renderer))
112 {
Jamie Madill526392d2018-11-16 09:35:14 -0500113 ANGLE_TRY(renderer->flush(contextVk));
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -0400114
115 ASSERT(!mQueryHelperTimeElapsedBegin.hasPendingWork(renderer));
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400116 ASSERT(!mQueryHelper.hasPendingWork(renderer));
117 }
118
119 // If the command buffer this query is being written to is still in flight, its reset command
120 // may not have been performed by the GPU yet. To avoid a race condition in this case, wait
121 // for the batch to finish first before querying (or return not-ready if not waiting).
122 ANGLE_TRY(renderer->checkCompletedCommands(contextVk));
Shahbaz Youssefic81e7bf2019-01-18 15:35:55 -0500123 if (renderer->isSerialInUse(mQueryHelper.getStoredQueueSerial()))
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400124 {
125 if (!wait)
126 {
Jamie Madill7c985f52018-11-29 18:16:17 -0500127 return angle::Result::Continue;
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400128 }
129 ANGLE_TRY(renderer->finishToSerial(contextVk, mQueryHelper.getStoredQueueSerial()));
130 }
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400131
132 VkQueryResultFlags flags = (wait ? VK_QUERY_RESULT_WAIT_BIT : 0) | VK_QUERY_RESULT_64_BIT;
133
Yuly Novikov27780292018-11-09 11:19:49 -0500134 VkResult result = mQueryHelper.getQueryPool()->getResults(
135 contextVk->getDevice(), mQueryHelper.getQuery(), 1, sizeof(mCachedResult), &mCachedResult,
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400136 sizeof(mCachedResult), flags);
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400137 // If the results are not ready, do nothing. mCachedResultValid remains false.
Yuly Novikov27780292018-11-09 11:19:49 -0500138 if (result == VK_NOT_READY)
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400139 {
Yuly Novikov27780292018-11-09 11:19:49 -0500140 // If VK_QUERY_RESULT_WAIT_BIT was given, VK_NOT_READY cannot have been returned.
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400141 ASSERT(!wait);
Jamie Madill7c985f52018-11-29 18:16:17 -0500142 return angle::Result::Continue;
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400143 }
Yuly Novikov27780292018-11-09 11:19:49 -0500144 ANGLE_VK_TRY(contextVk, result);
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400145
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400146 // Fix up the results to what OpenGL expects.
147 switch (getType())
148 {
149 case gl::QueryType::AnySamples:
150 case gl::QueryType::AnySamplesConservative:
151 // OpenGL query result in these cases is binary
152 mCachedResult = !!mCachedResult;
153 break;
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -0400154 case gl::QueryType::Timestamp:
155 break;
156 case gl::QueryType::TimeElapsed:
157 {
158 uint64_t timeElapsedEnd = mCachedResult;
159
160 result = mQueryHelperTimeElapsedBegin.getQueryPool()->getResults(
Yuly Novikov27780292018-11-09 11:19:49 -0500161 contextVk->getDevice(), mQueryHelperTimeElapsedBegin.getQuery(), 1,
162 sizeof(mCachedResult), &mCachedResult, sizeof(mCachedResult), flags);
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -0400163 // Since the result of the end query of time-elapsed is already available, the
164 // result of begin query must be available too.
Yuly Novikov27780292018-11-09 11:19:49 -0500165 ASSERT(result != VK_NOT_READY);
166 ANGLE_VK_TRY(contextVk, result);
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -0400167
168 mCachedResult = timeElapsedEnd - mCachedResult;
169 break;
170 }
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400171 default:
172 UNREACHABLE();
173 break;
174 }
175
176 mCachedResultValid = true;
Jamie Madill7c985f52018-11-29 18:16:17 -0500177 return angle::Result::Continue;
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400178}
Jamie Madillf4a789f2018-10-18 16:56:20 -0400179angle::Result QueryVk::getResult(const gl::Context *context, GLint *params)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400180{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400181 ANGLE_TRY(getResult(context, true));
182 *params = static_cast<GLint>(mCachedResult);
Jamie Madill7c985f52018-11-29 18:16:17 -0500183 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400184}
185
Jamie Madillf4a789f2018-10-18 16:56:20 -0400186angle::Result QueryVk::getResult(const gl::Context *context, GLuint *params)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400187{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400188 ANGLE_TRY(getResult(context, true));
189 *params = static_cast<GLuint>(mCachedResult);
Jamie Madill7c985f52018-11-29 18:16:17 -0500190 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400191}
192
Jamie Madillf4a789f2018-10-18 16:56:20 -0400193angle::Result QueryVk::getResult(const gl::Context *context, GLint64 *params)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400194{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400195 ANGLE_TRY(getResult(context, true));
196 *params = static_cast<GLint64>(mCachedResult);
Jamie Madill7c985f52018-11-29 18:16:17 -0500197 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400198}
199
Jamie Madillf4a789f2018-10-18 16:56:20 -0400200angle::Result QueryVk::getResult(const gl::Context *context, GLuint64 *params)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400201{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400202 ANGLE_TRY(getResult(context, true));
203 *params = mCachedResult;
Jamie Madill7c985f52018-11-29 18:16:17 -0500204 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400205}
206
Jamie Madillf4a789f2018-10-18 16:56:20 -0400207angle::Result QueryVk::isResultAvailable(const gl::Context *context, bool *available)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400208{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400209 ANGLE_TRY(getResult(context, false));
210 *available = mCachedResultValid;
211
Jamie Madill7c985f52018-11-29 18:16:17 -0500212 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400213}
214
215} // namespace rx