blob: 6535e58aa3069902d29c1bb6c3484326d0a0c229 [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
138 angle::Result result = mQueryHelper.getQueryPool()->getResults(
139 contextVk, mQueryHelper.getQuery(), 1, sizeof(mCachedResult), &mCachedResult,
140 sizeof(mCachedResult), flags);
141 ANGLE_TRY(result);
142
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400143 // If the results are not ready, do nothing. mCachedResultValid remains false.
144 if (result == angle::Result::Incomplete())
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400145 {
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400146 // If VK_QUERY_RESULT_WAIT_BIT was given, Incomplete() cannot have been returned.
147 ASSERT(!wait);
148 return angle::Result::Continue();
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400149 }
150
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400151 // Fix up the results to what OpenGL expects.
152 switch (getType())
153 {
154 case gl::QueryType::AnySamples:
155 case gl::QueryType::AnySamplesConservative:
156 // OpenGL query result in these cases is binary
157 mCachedResult = !!mCachedResult;
158 break;
Shahbaz Youssefic2b576d2018-10-12 14:45:34 -0400159 case gl::QueryType::Timestamp:
160 break;
161 case gl::QueryType::TimeElapsed:
162 {
163 uint64_t timeElapsedEnd = mCachedResult;
164
165 result = mQueryHelperTimeElapsedBegin.getQueryPool()->getResults(
166 contextVk, mQueryHelperTimeElapsedBegin.getQuery(), 1, sizeof(mCachedResult),
167 &mCachedResult, sizeof(mCachedResult), flags);
168 ANGLE_TRY(result);
169
170 // Since the result of the end query of time-elapsed is already available, the
171 // result of begin query must be available too.
172 ASSERT(result != angle::Result::Incomplete());
173
174 mCachedResult = timeElapsedEnd - mCachedResult;
175 break;
176 }
Shahbaz Youssefic4765aa2018-10-12 14:40:29 -0400177 default:
178 UNREACHABLE();
179 break;
180 }
181
182 mCachedResultValid = true;
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400183 return angle::Result::Continue();
184}
Jamie Madillf4a789f2018-10-18 16:56:20 -0400185angle::Result QueryVk::getResult(const gl::Context *context, GLint *params)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400186{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400187 ANGLE_TRY(getResult(context, true));
188 *params = static_cast<GLint>(mCachedResult);
Jamie Madillf4a789f2018-10-18 16:56:20 -0400189 return angle::Result::Continue();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400190}
191
Jamie Madillf4a789f2018-10-18 16:56:20 -0400192angle::Result QueryVk::getResult(const gl::Context *context, GLuint *params)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400193{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400194 ANGLE_TRY(getResult(context, true));
195 *params = static_cast<GLuint>(mCachedResult);
Jamie Madillf4a789f2018-10-18 16:56:20 -0400196 return angle::Result::Continue();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400197}
198
Jamie Madillf4a789f2018-10-18 16:56:20 -0400199angle::Result QueryVk::getResult(const gl::Context *context, GLint64 *params)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400200{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400201 ANGLE_TRY(getResult(context, true));
202 *params = static_cast<GLint64>(mCachedResult);
Jamie Madillf4a789f2018-10-18 16:56:20 -0400203 return angle::Result::Continue();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400204}
205
Jamie Madillf4a789f2018-10-18 16:56:20 -0400206angle::Result QueryVk::getResult(const gl::Context *context, GLuint64 *params)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400207{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400208 ANGLE_TRY(getResult(context, true));
209 *params = mCachedResult;
Jamie Madillf4a789f2018-10-18 16:56:20 -0400210 return angle::Result::Continue();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400211}
212
Jamie Madillf4a789f2018-10-18 16:56:20 -0400213angle::Result QueryVk::isResultAvailable(const gl::Context *context, bool *available)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400214{
Shahbaz Youssefi563fbaa2018-10-02 11:22:01 -0400215 ANGLE_TRY(getResult(context, false));
216 *available = mCachedResultValid;
217
Jamie Madillf4a789f2018-10-18 16:56:20 -0400218 return angle::Result::Continue();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400219}
220
221} // namespace rx