blob: 9e21117a5272645546ad470cd6e21f919515f843 [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
53 mQueryHelperTimeElapsedBegin.writeTimestamp(contextVk,
54 mQueryHelperTimeElapsedBegin.getQueryPool(),
55 mQueryHelperTimeElapsedBegin.getQuery());
56 }
57 else
58 {
59 mQueryHelper.beginQuery(contextVk, mQueryHelper.getQueryPool(), mQueryHelper.getQuery());
60 }
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040061
Jamie Madill7c985f52018-11-29 18:16:17 -050062 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -040063}
64
Jamie Madillf4a789f2018-10-18 16:56:20 -040065angle::Result QueryVk::end(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040066{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040067 ContextVk *contextVk = vk::GetImpl(context);
68
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -040069 if (getType() == gl::QueryType::TimeElapsed)
70 {
71 mQueryHelper.writeTimestamp(contextVk, mQueryHelper.getQueryPool(),
72 mQueryHelper.getQuery());
73 }
74 else
75 {
76 mQueryHelper.endQuery(contextVk, mQueryHelper.getQueryPool(), mQueryHelper.getQuery());
77 }
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -040078
Jamie Madill7c985f52018-11-29 18:16:17 -050079 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -040080}
81
Jamie Madillf4a789f2018-10-18 16:56:20 -040082angle::Result QueryVk::queryCounter(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040083{
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -040084 ContextVk *contextVk = vk::GetImpl(context);
85
86 mCachedResultValid = false;
87
88 if (!mQueryHelper.getQueryPool())
89 {
90 ANGLE_TRY(contextVk->getQueryPool(getType())->allocateQuery(contextVk, &mQueryHelper));
91 }
92
93 ASSERT(getType() == gl::QueryType::Timestamp);
94
95 mQueryHelper.writeTimestamp(contextVk, mQueryHelper.getQueryPool(), mQueryHelper.getQuery());
96
Jamie Madill7c985f52018-11-29 18:16:17 -050097 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -040098}
99
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400100angle::Result QueryVk::getResult(const gl::Context *context, bool wait)
101{
102 if (mCachedResultValid)
103 {
Jamie Madill7c985f52018-11-29 18:16:17 -0500104 return angle::Result::Continue;
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400105 }
106
107 ContextVk *contextVk = vk::GetImpl(context);
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400108 RendererVk *renderer = contextVk->getRenderer();
109
110 // glGetQueryObject* requires an implicit flush of the command buffers to guarantee execution in
111 // finite time.
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -0400112 // Note regarding time-elapsed: end should have been called after begin, so flushing when end
113 // has pending work should flush begin too.
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400114 if (mQueryHelper.hasPendingWork(renderer))
115 {
Jamie Madill526392d2018-11-16 09:35:14 -0500116 ANGLE_TRY(renderer->flush(contextVk));
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -0400117
118 ASSERT(!mQueryHelperTimeElapsedBegin.hasPendingWork(renderer));
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400119 ASSERT(!mQueryHelper.hasPendingWork(renderer));
120 }
121
122 // If the command buffer this query is being written to is still in flight, its reset command
123 // may not have been performed by the GPU yet. To avoid a race condition in this case, wait
124 // for the batch to finish first before querying (or return not-ready if not waiting).
125 ANGLE_TRY(renderer->checkCompletedCommands(contextVk));
126 if (mQueryHelper.isResourceInUse(renderer))
127 {
128 if (!wait)
129 {
Jamie Madill7c985f52018-11-29 18:16:17 -0500130 return angle::Result::Continue;
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400131 }
132 ANGLE_TRY(renderer->finishToSerial(contextVk, mQueryHelper.getStoredQueueSerial()));
133 }
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400134
135 VkQueryResultFlags flags = (wait ? VK_QUERY_RESULT_WAIT_BIT : 0) | VK_QUERY_RESULT_64_BIT;
136
Yuly Novikov27780292018-11-09 11:19:49 -0500137 VkResult result = mQueryHelper.getQueryPool()->getResults(
138 contextVk->getDevice(), mQueryHelper.getQuery(), 1, sizeof(mCachedResult), &mCachedResult,
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400139 sizeof(mCachedResult), flags);
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400140 // If the results are not ready, do nothing. mCachedResultValid remains false.
Yuly Novikov27780292018-11-09 11:19:49 -0500141 if (result == VK_NOT_READY)
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400142 {
Yuly Novikov27780292018-11-09 11:19:49 -0500143 // If VK_QUERY_RESULT_WAIT_BIT was given, VK_NOT_READY cannot have been returned.
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400144 ASSERT(!wait);
Jamie Madill7c985f52018-11-29 18:16:17 -0500145 return angle::Result::Continue;
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400146 }
Yuly Novikov27780292018-11-09 11:19:49 -0500147 ANGLE_VK_TRY(contextVk, result);
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400148
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400149 // Fix up the results to what OpenGL expects.
150 switch (getType())
151 {
152 case gl::QueryType::AnySamples:
153 case gl::QueryType::AnySamplesConservative:
154 // OpenGL query result in these cases is binary
155 mCachedResult = !!mCachedResult;
156 break;
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -0400157 case gl::QueryType::Timestamp:
158 break;
159 case gl::QueryType::TimeElapsed:
160 {
161 uint64_t timeElapsedEnd = mCachedResult;
162
163 result = mQueryHelperTimeElapsedBegin.getQueryPool()->getResults(
Yuly Novikov27780292018-11-09 11:19:49 -0500164 contextVk->getDevice(), mQueryHelperTimeElapsedBegin.getQuery(), 1,
165 sizeof(mCachedResult), &mCachedResult, sizeof(mCachedResult), flags);
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -0400166 // Since the result of the end query of time-elapsed is already available, the
167 // result of begin query must be available too.
Yuly Novikov27780292018-11-09 11:19:49 -0500168 ASSERT(result != VK_NOT_READY);
169 ANGLE_VK_TRY(contextVk, result);
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -0400170
171 mCachedResult = timeElapsedEnd - mCachedResult;
172 break;
173 }
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400174 default:
175 UNREACHABLE();
176 break;
177 }
178
179 mCachedResultValid = true;
Jamie Madill7c985f52018-11-29 18:16:17 -0500180 return angle::Result::Continue;
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400181}
Jamie Madillf4a789f2018-10-18 16:56:20 -0400182angle::Result QueryVk::getResult(const gl::Context *context, GLint *params)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400183{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400184 ANGLE_TRY(getResult(context, true));
185 *params = static_cast<GLint>(mCachedResult);
Jamie Madill7c985f52018-11-29 18:16:17 -0500186 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400187}
188
Jamie Madillf4a789f2018-10-18 16:56:20 -0400189angle::Result QueryVk::getResult(const gl::Context *context, GLuint *params)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400190{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400191 ANGLE_TRY(getResult(context, true));
192 *params = static_cast<GLuint>(mCachedResult);
Jamie Madill7c985f52018-11-29 18:16:17 -0500193 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400194}
195
Jamie Madillf4a789f2018-10-18 16:56:20 -0400196angle::Result QueryVk::getResult(const gl::Context *context, GLint64 *params)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400197{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400198 ANGLE_TRY(getResult(context, true));
199 *params = static_cast<GLint64>(mCachedResult);
Jamie Madill7c985f52018-11-29 18:16:17 -0500200 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400201}
202
Jamie Madillf4a789f2018-10-18 16:56:20 -0400203angle::Result QueryVk::getResult(const gl::Context *context, GLuint64 *params)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400204{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400205 ANGLE_TRY(getResult(context, true));
206 *params = mCachedResult;
Jamie Madill7c985f52018-11-29 18:16:17 -0500207 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400208}
209
Jamie Madillf4a789f2018-10-18 16:56:20 -0400210angle::Result QueryVk::isResultAvailable(const gl::Context *context, bool *available)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400211{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400212 ANGLE_TRY(getResult(context, false));
213 *available = mCachedResultValid;
214
Jamie Madill7c985f52018-11-29 18:16:17 -0500215 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400216}
217
218} // namespace rx