Commit 89f2845c by Ian Ewell Committed by Commit Bot

Context virtualization for D3D11 queries

Queries in D3D11 are now virtualized such that they work as expected with multiple contexts. Timer queries now only time the operations that their context is responsible for and the operations of other contexts are ignored. BUG=angleproject:657 Change-Id: I667de594bdb5831d126d5801c0e692ded4c88bf4 Reviewed-on: https://chromium-review.googlesource.com/327150Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Ian Ewell <ewell@google.com>
parent dc107978
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#ifndef LIBANGLE_RENDERER_D3D_D3D11_QUERY11_H_ #ifndef LIBANGLE_RENDERER_D3D_D3D11_QUERY11_H_
#define LIBANGLE_RENDERER_D3D_D3D11_QUERY11_H_ #define LIBANGLE_RENDERER_D3D_D3D11_QUERY11_H_
#include <deque>
#include "libANGLE/renderer/QueryImpl.h" #include "libANGLE/renderer/QueryImpl.h"
namespace rx namespace rx
...@@ -19,31 +21,46 @@ class Query11 : public QueryImpl ...@@ -19,31 +21,46 @@ class Query11 : public QueryImpl
{ {
public: public:
Query11(Renderer11 *renderer, GLenum type); Query11(Renderer11 *renderer, GLenum type);
virtual ~Query11(); ~Query11() override;
gl::Error begin() override;
gl::Error end() override;
gl::Error queryCounter() override;
gl::Error getResult(GLint *params) override;
gl::Error getResult(GLuint *params) override;
gl::Error getResult(GLint64 *params) override;
gl::Error getResult(GLuint64 *params) override;
gl::Error isResultAvailable(bool *available) override;
virtual gl::Error begin(); gl::Error pause();
virtual gl::Error end(); gl::Error resume();
virtual gl::Error queryCounter();
virtual gl::Error getResult(GLint *params);
virtual gl::Error getResult(GLuint *params);
virtual gl::Error getResult(GLint64 *params);
virtual gl::Error getResult(GLuint64 *params);
virtual gl::Error isResultAvailable(bool *available);
private: private:
gl::Error testQuery(); struct QueryState
{
QueryState()
: query(nullptr), beginTimestamp(nullptr), endTimestamp(nullptr), finished(false)
{
}
ID3D11Query *query;
ID3D11Query *beginTimestamp;
ID3D11Query *endTimestamp;
bool finished;
};
gl::Error flush(bool force);
gl::Error testQuery(QueryState *queryState);
template <typename T> template <typename T>
gl::Error getResultBase(T *params); gl::Error getResultBase(T *params);
GLuint64 mResult; GLuint64 mResult;
GLuint64 mResultSum;
bool mQueryFinished;
Renderer11 *mRenderer; Renderer11 *mRenderer;
ID3D11Query *mQuery;
ID3D11Query *mTimestampBeginQuery; QueryState mActiveQuery;
ID3D11Query *mTimestampEndQuery; std::deque<QueryState> mPendingQueries;
}; };
} }
......
...@@ -3974,6 +3974,11 @@ void Renderer11::onBufferDelete(const Buffer11 *deleted) ...@@ -3974,6 +3974,11 @@ void Renderer11::onBufferDelete(const Buffer11 *deleted)
mAliveBuffers.erase(deleted); mAliveBuffers.erase(deleted);
} }
void Renderer11::onMakeCurrent(const gl::Data &data)
{
mStateManager.onMakeCurrent(data);
}
ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource) ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource)
{ {
D3D11_TEXTURE2D_DESC textureDesc; D3D11_TEXTURE2D_DESC textureDesc;
......
...@@ -287,6 +287,7 @@ class Renderer11 : public RendererD3D ...@@ -287,6 +287,7 @@ class Renderer11 : public RendererD3D
void onSwap(); void onSwap();
void onBufferDelete(const Buffer11 *deleted); void onBufferDelete(const Buffer11 *deleted);
void onMakeCurrent(const gl::Data &data) override;
egl::Error getEGLDevice(DeviceImpl **device) override; egl::Error getEGLDevice(DeviceImpl **device) override;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "common/BitSetIterator.h" #include "common/BitSetIterator.h"
#include "common/utilities.h" #include "common/utilities.h"
#include "libANGLE/Query.h"
#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h" #include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
...@@ -128,6 +129,9 @@ void StateManager11::SRVCache::clear() ...@@ -128,6 +129,9 @@ void StateManager11::SRVCache::clear()
mHighestUsedSRV = 0; mHighestUsedSRV = 0;
} }
static const GLenum QueryTypes[] = {GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_TIME_ELAPSED_EXT};
StateManager11::StateManager11(Renderer11 *renderer) StateManager11::StateManager11(Renderer11 *renderer)
: mRenderer(renderer), : mRenderer(renderer),
mBlendStateIsDirty(false), mBlendStateIsDirty(false),
...@@ -825,6 +829,40 @@ void StateManager11::setRenderTarget(ID3D11RenderTargetView *renderTarget, ...@@ -825,6 +829,40 @@ void StateManager11::setRenderTarget(ID3D11RenderTargetView *renderTarget,
mRenderer->getDeviceContext()->OMSetRenderTargets(1, &renderTarget, depthStencil); mRenderer->getDeviceContext()->OMSetRenderTargets(1, &renderTarget, depthStencil);
} }
void StateManager11::onBeginQuery(Query11 *query)
{
mCurrentQueries.insert(query);
}
void StateManager11::onDeleteQueryObject(Query11 *query)
{
mCurrentQueries.erase(query);
}
gl::Error StateManager11::onMakeCurrent(const gl::Data &data)
{
const gl::State &state = *data.state;
for (Query11 *query : mCurrentQueries)
{
query->pause();
}
mCurrentQueries.clear();
for (GLenum queryType : QueryTypes)
{
gl::Query *query = state.getActiveQuery(queryType);
if (query != nullptr)
{
Query11 *query11 = GetImplAs<Query11>(query);
query11->resume();
mCurrentQueries.insert(query11);
}
}
return gl::Error(GL_NO_ERROR);
}
void StateManager11::setShaderResource(gl::SamplerType shaderType, void StateManager11::setShaderResource(gl::SamplerType shaderType,
UINT resourceSlot, UINT resourceSlot,
ID3D11ShaderResourceView *srv) ID3D11ShaderResourceView *srv)
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "libANGLE/State.h" #include "libANGLE/State.h"
#include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h" #include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/d3d11/Query11.h"
#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/RendererD3D.h"
namespace rx namespace rx
...@@ -84,6 +85,10 @@ class StateManager11 final : angle::NonCopyable ...@@ -84,6 +85,10 @@ class StateManager11 final : angle::NonCopyable
void setRenderTarget(ID3D11RenderTargetView *renderTarget, void setRenderTarget(ID3D11RenderTargetView *renderTarget,
ID3D11DepthStencilView *depthStencil); ID3D11DepthStencilView *depthStencil);
void onBeginQuery(Query11 *query);
void onDeleteQueryObject(Query11 *query);
gl::Error onMakeCurrent(const gl::Data &data);
private: private:
void unsetConflictingSRVs(gl::SamplerType shaderType, void unsetConflictingSRVs(gl::SamplerType shaderType,
uintptr_t resource, uintptr_t resource,
...@@ -139,6 +144,9 @@ class StateManager11 final : angle::NonCopyable ...@@ -139,6 +144,9 @@ class StateManager11 final : angle::NonCopyable
std::array<uintptr_t, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS> mAppliedRTVs; std::array<uintptr_t, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS> mAppliedRTVs;
uintptr_t mAppliedDSV; uintptr_t mAppliedDSV;
// Queries that are currently active in this state
std::set<Query11 *> mCurrentQueries;
// Currently applied textures // Currently applied textures
struct SRVRecord struct SRVRecord
{ {
......
...@@ -308,14 +308,10 @@ TEST_P(TimerQueriesTest, TimeElapsedMulticontextTest) ...@@ -308,14 +308,10 @@ TEST_P(TimerQueriesTest, TimeElapsedMulticontextTest)
return; return;
} }
// D3D multicontext isn't implemented yet // Without a glClear, the first draw call on GL takes a huge amount of time when run after the
if (GetParam() == ES3_D3D11() || GetParam() == ES2_D3D11()) // D3D test on certain NVIDIA drivers
{ glDepthMask(GL_TRUE);
std::cout glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
<< "Test skipped because the D3D backends cannot support simultaneous timer queries yet"
<< std::endl;
return;
}
EGLint contextAttributes[] = { EGLint contextAttributes[] = {
EGL_CONTEXT_MAJOR_VERSION_KHR, EGL_CONTEXT_MAJOR_VERSION_KHR,
...@@ -415,15 +411,6 @@ TEST_P(TimerQueriesTest, TimeElapsedMulticontextTest) ...@@ -415,15 +411,6 @@ TEST_P(TimerQueriesTest, TimeElapsedMulticontextTest)
// Go back to the first context, end its query, and get the result // Go back to the first context, end its query, and get the result
eglMakeCurrent(display, surface, surface, contexts[0].context); eglMakeCurrent(display, surface, surface, contexts[0].context);
glEndQueryEXT(GL_TIME_ELAPSED_EXT); glEndQueryEXT(GL_TIME_ELAPSED_EXT);
int timeout = 20000;
GLuint ready = GL_FALSE;
while (ready == GL_FALSE && timeout > 0)
{
angle::Sleep(0);
glGetQueryObjectuivEXT(contexts[0].query, GL_QUERY_RESULT_AVAILABLE_EXT, &ready);
timeout--;
}
ASSERT_LT(0, timeout) << "Query result available timed out" << std::endl;
GLuint64 result1 = 0; GLuint64 result1 = 0;
GLuint64 result2 = 0; GLuint64 result2 = 0;
...@@ -432,17 +419,8 @@ TEST_P(TimerQueriesTest, TimeElapsedMulticontextTest) ...@@ -432,17 +419,8 @@ TEST_P(TimerQueriesTest, TimeElapsedMulticontextTest)
glDeleteProgram(contexts[0].program); glDeleteProgram(contexts[0].program);
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
// Get the 2nd contexts results // Get the 2nd context's results
eglMakeCurrent(display, surface, surface, contexts[1].context); eglMakeCurrent(display, surface, surface, contexts[1].context);
timeout = 20000;
ready = GL_FALSE;
while (ready == GL_FALSE && timeout > 0)
{
angle::Sleep(0);
glGetQueryObjectuivEXT(contexts[1].query, GL_QUERY_RESULT_AVAILABLE_EXT, &ready);
timeout--;
}
ASSERT_LT(0, timeout) << "Query result available timed out" << std::endl;
glGetQueryObjectui64vEXT(contexts[1].query, GL_QUERY_RESULT_EXT, &result2); glGetQueryObjectui64vEXT(contexts[1].query, GL_QUERY_RESULT_EXT, &result2);
glDeleteQueriesEXT(1, &contexts[1].query); glDeleteQueriesEXT(1, &contexts[1].query);
glDeleteProgram(contexts[1].program); glDeleteProgram(contexts[1].program);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment