blob: b71085114dfc091ecd1abd9859170fefeda6d3a3 [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 Madill9e54b5a2016-05-25 12:57:39 -040021{
22}
23
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040024QueryVk::~QueryVk() = default;
25
Jamie Madillf4a789f2018-10-18 16:56:20 -040026void QueryVk::onDestroy(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040027{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040028 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madillf4a789f2018-10-18 16:56:20 -040029 vk::DynamicQueryPool *queryPool = contextVk->getQueryPool(getType());
30 queryPool->freeQuery(contextVk, &mQueryHelper);
31 queryPool->freeQuery(contextVk, &mQueryHelperTimeElapsedBegin);
Jamie Madill9e54b5a2016-05-25 12:57:39 -040032}
33
Jamie Madillf4a789f2018-10-18 16:56:20 -040034angle::Result QueryVk::begin(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040035{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040036 ContextVk *contextVk = vk::GetImpl(context);
37
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040038 mCachedResultValid = false;
39
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -040040 if (!mQueryHelper.getQueryPool())
41 {
42 ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(contextVk, &mQueryHelper));
43 }
44
45 // Note: TimeElapsed is implemented by using two Timestamp queries and taking the diff.
46 if (getType() == gl::QueryType::TimeElapsed)
47 {
48 if (!mQueryHelperTimeElapsedBegin.getQueryPool())
49 {
50 ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(
51 contextVk, &mQueryHelperTimeElapsedBegin));
52 }
53
54 mQueryHelperTimeElapsedBegin.writeTimestamp(contextVk,
55 mQueryHelperTimeElapsedBegin.getQueryPool(),
56 mQueryHelperTimeElapsedBegin.getQuery());
57 }
58 else
59 {
60 mQueryHelper.beginQuery(contextVk, mQueryHelper.getQueryPool(), mQueryHelper.getQuery());
61 }
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040062
Jamie Madillf4a789f2018-10-18 16:56:20 -040063 return angle::Result::Continue();
Jamie Madill9e54b5a2016-05-25 12:57:39 -040064}
65
Jamie Madillf4a789f2018-10-18 16:56:20 -040066angle::Result QueryVk::end(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040067{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040068 ContextVk *contextVk = vk::GetImpl(context);
69
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -040070 if (getType() == gl::QueryType::TimeElapsed)
71 {
72 mQueryHelper.writeTimestamp(contextVk, mQueryHelper.getQueryPool(),
73 mQueryHelper.getQuery());
74 }
75 else
76 {
77 mQueryHelper.endQuery(contextVk, mQueryHelper.getQueryPool(), mQueryHelper.getQuery());
78 }
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040079
Jamie Madillf4a789f2018-10-18 16:56:20 -040080 return angle::Result::Continue();
Jamie Madill9e54b5a2016-05-25 12:57:39 -040081}
82
Jamie Madillf4a789f2018-10-18 16:56:20 -040083angle::Result QueryVk::queryCounter(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040084{
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -040085 ContextVk *contextVk = vk::GetImpl(context);
86
87 mCachedResultValid = false;
88
89 if (!mQueryHelper.getQueryPool())
90 {
91 ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(contextVk, &mQueryHelper));
92 }
93
94 ASSERT(getType() == gl::QueryType::Timestamp);
95
96 mQueryHelper.writeTimestamp(contextVk, mQueryHelper.getQueryPool(), mQueryHelper.getQuery());
97
Jamie Madillf4a789f2018-10-18 16:56:20 -040098 return angle::Result::Continue();
Jamie Madill9e54b5a2016-05-25 12:57:39 -040099}
100
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400101angle::Result QueryVk::getResult(const gl::Context *context, bool wait)
102{
103 if (mCachedResultValid)
104 {
105 return angle::Result::Continue();
106 }
107
108 ContextVk *contextVk = vk::GetImpl(context);
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400109 RendererVk *renderer = contextVk->getRenderer();
110
111 // glGetQueryObject* requires an implicit flush of the command buffers to guarantee execution in
112 // finite time.
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -0400113 // Note regarding time-elapsed: end should have been called after begin, so flushing when end
114 // has pending work should flush begin too.
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400115 if (mQueryHelper.hasPendingWork(renderer))
116 {
117 ANGLE_TRY_HANDLE(context, renderer->flush(contextVk));
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -0400118
119 ASSERT(!mQueryHelperTimeElapsedBegin.hasPendingWork(renderer));
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400120 ASSERT(!mQueryHelper.hasPendingWork(renderer));
121 }
122
123 // If the command buffer this query is being written to is still in flight, its reset command
124 // may not have been performed by the GPU yet. To avoid a race condition in this case, wait
125 // for the batch to finish first before querying (or return not-ready if not waiting).
126 ANGLE_TRY(renderer->checkCompletedCommands(contextVk));
127 if (mQueryHelper.isResourceInUse(renderer))
128 {
129 if (!wait)
130 {
131 return angle::Result::Continue();
132 }
133 ANGLE_TRY(renderer->finishToSerial(contextVk, mQueryHelper.getStoredQueueSerial()));
134 }
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400135
136 VkQueryResultFlags flags = (wait ? VK_QUERY_RESULT_WAIT_BIT : 0) | VK_QUERY_RESULT_64_BIT;
137
Yuly Novikov27780292018-11-09 11:19:49 -0500138 VkResult result = mQueryHelper.getQueryPool()->getResults(
139 contextVk->getDevice(), mQueryHelper.getQuery(), 1, sizeof(mCachedResult), &mCachedResult,
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400140 sizeof(mCachedResult), flags);
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400141 // If the results are not ready, do nothing. mCachedResultValid remains false.
Yuly Novikov27780292018-11-09 11:19:49 -0500142 if (result == VK_NOT_READY)
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400143 {
Yuly Novikov27780292018-11-09 11:19:49 -0500144 // If VK_QUERY_RESULT_WAIT_BIT was given, VK_NOT_READY cannot have been returned.
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400145 ASSERT(!wait);
146 return angle::Result::Continue();
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400147 }
Yuly Novikov27780292018-11-09 11:19:49 -0500148 ANGLE_VK_TRY(contextVk, result);
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400149
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400150 // Fix up the results to what OpenGL expects.
151 switch (getType())
152 {
153 case gl::QueryType::AnySamples:
154 case gl::QueryType::AnySamplesConservative:
155 // OpenGL query result in these cases is binary
156 mCachedResult = !!mCachedResult;
157 break;
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -0400158 case gl::QueryType::Timestamp:
159 break;
160 case gl::QueryType::TimeElapsed:
161 {
162 uint64_t timeElapsedEnd = mCachedResult;
163
164 result = mQueryHelperTimeElapsedBegin.getQueryPool()->getResults(
Yuly Novikov27780292018-11-09 11:19:49 -0500165 contextVk->getDevice(), mQueryHelperTimeElapsedBegin.getQuery(), 1,
166 sizeof(mCachedResult), &mCachedResult, sizeof(mCachedResult), flags);
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -0400167 // Since the result of the end query of time-elapsed is already available, the
168 // result of begin query must be available too.
Yuly Novikov27780292018-11-09 11:19:49 -0500169 ASSERT(result != VK_NOT_READY);
170 ANGLE_VK_TRY(contextVk, result);
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -0400171
172 mCachedResult = timeElapsedEnd - mCachedResult;
173 break;
174 }
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400175 default:
176 UNREACHABLE();
177 break;
178 }
179
180 mCachedResultValid = true;
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400181 return angle::Result::Continue();
182}
Jamie Madillf4a789f2018-10-18 16:56:20 -0400183angle::Result QueryVk::getResult(const gl::Context *context, GLint *params)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400184{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400185 ANGLE_TRY(getResult(context, true));
186 *params = static_cast<GLint>(mCachedResult);
Jamie Madillf4a789f2018-10-18 16:56:20 -0400187 return angle::Result::Continue();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400188}
189
Jamie Madillf4a789f2018-10-18 16:56:20 -0400190angle::Result QueryVk::getResult(const gl::Context *context, GLuint *params)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400191{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400192 ANGLE_TRY(getResult(context, true));
193 *params = static_cast<GLuint>(mCachedResult);
Jamie Madillf4a789f2018-10-18 16:56:20 -0400194 return angle::Result::Continue();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400195}
196
Jamie Madillf4a789f2018-10-18 16:56:20 -0400197angle::Result QueryVk::getResult(const gl::Context *context, GLint64 *params)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400198{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400199 ANGLE_TRY(getResult(context, true));
200 *params = static_cast<GLint64>(mCachedResult);
Jamie Madillf4a789f2018-10-18 16:56:20 -0400201 return angle::Result::Continue();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400202}
203
Jamie Madillf4a789f2018-10-18 16:56:20 -0400204angle::Result QueryVk::getResult(const gl::Context *context, GLuint64 *params)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400205{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400206 ANGLE_TRY(getResult(context, true));
207 *params = mCachedResult;
Jamie Madillf4a789f2018-10-18 16:56:20 -0400208 return angle::Result::Continue();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400209}
210
Jamie Madillf4a789f2018-10-18 16:56:20 -0400211angle::Result QueryVk::isResultAvailable(const gl::Context *context, bool *available)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400212{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400213 ANGLE_TRY(getResult(context, false));
214 *available = mCachedResultValid;
215
Jamie Madillf4a789f2018-10-18 16:56:20 -0400216 return angle::Result::Continue();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400217}
218
219} // namespace rx