Skip to content

Commit c5b955b

Browse files
committed
More validations for InheritanceInfo and ActiveQueries within renderpasses
1 parent ceb270b commit c5b955b

File tree

3 files changed

+60
-10
lines changed

3 files changed

+60
-10
lines changed

include/nbl/video/IGPUCommandBuffer.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ class IGPUCommandBuffer :
8484
return false;
8585
}
8686

87+
if (inheritanceInfo != nullptr)
88+
m_cachedInheritanceInfo = *inheritanceInfo;
89+
8790
return base_t::begin(_flags);
8891
}
8992

@@ -166,6 +169,11 @@ class IGPUCommandBuffer :
166169
return true;
167170
}
168171

172+
SInheritanceInfo getCachedInheritanceInfo() const
173+
{
174+
return m_cachedInheritanceInfo;
175+
}
176+
169177
protected:
170178
friend class IGPUQueue;
171179

@@ -175,7 +183,7 @@ class IGPUCommandBuffer :
175183
virtual ~IGPUCommandBuffer() = default;
176184

177185
core::smart_refctd_ptr<IGPUCommandPool> m_cmdpool;
178-
186+
SInheritanceInfo m_cachedInheritanceInfo;
179187

180188
inline bool validate_updateBuffer(IGPUBuffer* dstBuffer, size_t dstOffset, size_t dataSize, const void* pData)
181189
{

src/nbl/video/COpenGLCommandBuffer.cpp

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -864,14 +864,16 @@ COpenGLCommandBuffer::~COpenGLCommandBuffer()
864864
{
865865
auto& c = cmd.get<impl::ECT_BEGIN_RENDERPASS>();
866866
auto framebuf = core::smart_refctd_ptr_static_cast<const COpenGLFramebuffer>(c.renderpassBegin.framebuffer);
867-
867+
868868
ctxlocal->nextState.framebuffer.hash = framebuf->getHashValue();
869869
ctxlocal->nextState.framebuffer.fbo = std::move(framebuf);
870870
ctxlocal->flushStateGraphics(gl, SOpenGLContextLocalCache::GSB_FRAMEBUFFER, ctxid);
871871

872872
GLuint fbo = ctxlocal->currentState.framebuffer.GLname;
873873
if (fbo)
874874
beginRenderpass_clearAttachments(gl, ctxlocal, ctxid, c.renderpassBegin, fbo, m_logger.getOptRawPtr());
875+
876+
currentlyRecordingRenderPass = c.renderpassBegin.renderpass.get();
875877
}
876878
break;
877879
case impl::ECT_NEXT_SUBPASS:
@@ -887,6 +889,7 @@ COpenGLCommandBuffer::~COpenGLCommandBuffer()
887889
ctxlocal->nextState.framebuffer.hash = SOpenGLState::NULL_FBO_HASH;
888890
ctxlocal->nextState.framebuffer.GLname = 0u;
889891
ctxlocal->nextState.framebuffer.fbo = nullptr;
892+
currentlyRecordingRenderPass = nullptr;
890893
}
891894
break;
892895
case impl::ECT_SET_DEVICE_MASK:
@@ -928,10 +931,18 @@ COpenGLCommandBuffer::~COpenGLCommandBuffer()
928931
auto& c = cmd.get<impl::ECT_BEGIN_QUERY>();
929932
const COpenGLQueryPool* qp = static_cast<const COpenGLQueryPool*>(c.queryPool.get());
930933
auto currentQuery = core::bitflag(qp->getCreationParameters().queryType);
931-
if(!queriesUsed.hasValue(currentQuery))
934+
if(!queriesActive.hasValue(currentQuery))
932935
{
933936
qp->beginQuery(gl, ctxid, c.query, c.flags.value);
934-
queriesUsed |= currentQuery;
937+
queriesActive |= currentQuery;
938+
939+
uint32_t queryTypeIndex = std::log2<uint32_t>(currentQuery.value);
940+
currentlyRecordingQueries[queryTypeIndex] = std::make_tuple(
941+
qp,
942+
c.query,
943+
currentlyRecordingRenderPass,
944+
0u
945+
);
935946
}
936947
else
937948
{
@@ -941,12 +952,36 @@ COpenGLCommandBuffer::~COpenGLCommandBuffer()
941952
break;
942953
case impl::ECT_END_QUERY:
943954
{
944-
// TODO: set last queue to use
945955
auto& c = cmd.get<impl::ECT_END_QUERY>();
946956
const COpenGLQueryPool* qp = static_cast<const COpenGLQueryPool*>(c.queryPool.get());
947957
auto currentQuery = core::bitflag(qp->getCreationParameters().queryType);
948-
qp->endQuery(gl, ctxid, c.query);
949-
queriesUsed &= ~currentQuery;
958+
if(queriesActive.hasValue(currentQuery))
959+
{
960+
uint32_t queryTypeIndex = std::log2<uint32_t>(currentQuery.value);
961+
IQueryPool const * currentQueryPool = std::get<0>(currentlyRecordingQueries[queryTypeIndex]);
962+
uint32_t currentQueryIndex = std::get<1>(currentlyRecordingQueries[queryTypeIndex]);
963+
renderpass_t const * currentQueryRenderpass = std::get<2>(currentlyRecordingQueries[queryTypeIndex]);
964+
uint32_t currentQuerySubpassIndex = std::get<3>(currentlyRecordingQueries[queryTypeIndex]);
965+
966+
if(currentQueryPool != c.queryPool.get() || currentQueryIndex != c.query)
967+
{
968+
assert(false); // You must end the same query you began for every query type.
969+
break;
970+
}
971+
if(currentQueryRenderpass != currentlyRecordingRenderPass)
972+
{
973+
assert(false); // Query either starts and ends in the same subpass or starts and ends entirely outside a renderpass
974+
break;
975+
}
976+
977+
// currentlyRecordingQuery assert tuple -> same query index and query pool -> same renderpass
978+
qp->endQuery(gl, ctxid, c.query);
979+
queriesActive &= ~currentQuery;
980+
}
981+
else
982+
{
983+
assert(false); // QueryType was not active to end.
984+
}
950985
}
951986
break;
952987
case impl::ECT_COPY_QUERY_POOL_RESULTS:
@@ -1259,7 +1294,12 @@ COpenGLCommandBuffer::~COpenGLCommandBuffer()
12591294
case impl::ECT_EXECUTE_COMMANDS:
12601295
{
12611296
auto& c = cmd.get<impl::ECT_EXECUTE_COMMANDS>();
1262-
1297+
auto inheritanceInfo = c.cmdbuf->getCachedInheritanceInfo();
1298+
if(queriesActive.hasValue(IQueryPool::EQT_OCCLUSION))
1299+
{
1300+
// For a secondary command buffer to be executed while a query is active, it must set the occlusionQueryEnable, queryFlags, and/or pipelineStatistics members of InheritanceInfo to conservative values
1301+
assert(inheritanceInfo.occlusionQueryEnable);
1302+
}
12631303
static_cast<COpenGLCommandBuffer*>(c.cmdbuf.get())->executeAll(gl, ctxlocal, ctxid);
12641304
}
12651305
break;

src/nbl/video/COpenGLCommandBuffer.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -533,8 +533,9 @@ class COpenGLCommandBuffer final : public IGPUCommandBuffer
533533
}
534534
core::vector<SCommand> m_commands; // TODO: embed in the command pool via the use of linked list
535535
const COpenGLFeatureMap* m_features;
536-
mutable core::bitflag<IQueryPool::E_QUERY_TYPE> queriesUsed;
537-
mutable std::tuple<IQueryPool*,uint32_t/*query ix*/,renderpass_t*,uint32_t/*subpass ix*/> currentlyRecordingQuery[IQueryPool::EQT_COUNT];
536+
mutable renderpass_t const * currentlyRecordingRenderPass = nullptr;
537+
mutable core::bitflag<IQueryPool::E_QUERY_TYPE> queriesActive;
538+
mutable std::tuple<IQueryPool const *,uint32_t/*query ix*/,renderpass_t const *,uint32_t/*subpass ix*/> currentlyRecordingQueries[IQueryPool::EQT_COUNT];
538539

539540
public:
540541
void executeAll(IOpenGL_FunctionTable* gl, SOpenGLContextLocalCache* ctxlocal, uint32_t ctxid) const;
@@ -554,6 +555,7 @@ class COpenGLCommandBuffer final : public IGPUCommandBuffer
554555

555556
inline bool end() override final
556557
{
558+
assert(queriesActive.value == 0u); // No Queries should be active when command buffer ends
557559
return IGPUCommandBuffer::end();
558560
}
559561
bool reset(uint32_t _flags) override final;

0 commit comments

Comments
 (0)