@@ -919,102 +919,146 @@ COpenGLCommandBuffer::~COpenGLCommandBuffer()
919
919
{
920
920
auto & c = cmd.get <impl::ECT_RESET_QUERY_POOL>();
921
921
COpenGLQueryPool* qp = static_cast <COpenGLQueryPool*>(c.queryPool .get ());
922
- bool success = qp->resetQueries (gl, c.query , c.queryCount );
922
+ bool success = qp->resetQueries (gl, ctxid, c.query , c.queryCount );
923
923
assert (success);
924
924
}
925
925
break ;
926
926
case impl::ECT_BEGIN_QUERY:
927
927
{
928
928
auto & c = cmd.get <impl::ECT_BEGIN_QUERY>();
929
929
const COpenGLQueryPool* qp = static_cast <const COpenGLQueryPool*>(c.queryPool .get ());
930
- qp->beginQuery (gl, c.query , c.flags .value );
930
+ qp->beginQuery (gl, ctxid, c.query , c.flags .value );
931
931
}
932
932
break ;
933
933
case impl::ECT_END_QUERY:
934
934
{
935
+ // TODO: set last queue to use
935
936
auto & c = cmd.get <impl::ECT_END_QUERY>();
936
937
const COpenGLQueryPool* qp = static_cast <const COpenGLQueryPool*>(c.queryPool .get ());
937
- qp->endQuery (gl, c.query );
938
+ qp->endQuery (gl, ctxid, c.query );
938
939
}
939
940
break ;
940
941
case impl::ECT_COPY_QUERY_POOL_RESULTS:
941
942
{
942
943
auto & c = cmd.get <impl::ECT_COPY_QUERY_POOL_RESULTS>();
943
944
944
945
const COpenGLBuffer* buffer = static_cast <const COpenGLBuffer*>(c.dstBuffer .get ());
945
- GLuint bufferId = buffer->getOpenGLName ();
946
-
947
- const COpenGLQueryPool* qp = static_cast <const COpenGLQueryPool*>(c.queryPool .get ());
948
-
946
+ const COpenGLQueryPool* qp = IBackendObject::compatibility_cast<const COpenGLQueryPool*>(c.queryPool .get (), this );
949
947
auto queryPoolQueriesCount = qp->getCreationParameters ().queryCount ;
950
- auto queriesRange = qp->getQueries (); // queriesRange.size() is a multiple of queryPoolQueriesCount
951
- auto queries = queriesRange.begin ();
952
-
953
- IQueryPool::E_QUERY_TYPE queryType = qp->getCreationParameters ().queryType ;
954
- bool use64Version = c.flags .hasValue (IQueryPool::E_QUERY_RESULTS_FLAGS::EQRF_64_BIT);
955
- bool availabilityFlag = c.flags .hasValue (IQueryPool::E_QUERY_RESULTS_FLAGS::EQRF_WITH_AVAILABILITY_BIT);
956
- bool waitForAllResults = c.flags .hasValue (IQueryPool::E_QUERY_RESULTS_FLAGS::EQRF_WAIT_BIT);
957
- bool partialResults = c.flags .hasValue (IQueryPool::E_QUERY_RESULTS_FLAGS::EQRF_PARTIAL_BIT);
958
948
959
- if (c. firstQuery + c. queryCount > queryPoolQueriesCount )
949
+ if (buffer != nullptr && qp != nullptr )
960
950
{
961
- assert (false && " The sum of firstQuery and queryCount must be less than or equal to the number of queries in queryPool" );
962
- break ;
963
- }
964
- if (partialResults && queryType == IQueryPool::E_QUERY_TYPE::EQT_TIMESTAMP) {
965
- assert (false && " QUERY_RESULT_PARTIAL_BIT must not be used if the pools queryType is QUERY_TYPE_TIMESTAMP." );
966
- break ;
967
- }
951
+ GLuint bufferId = buffer->getOpenGLName ();
968
952
969
- size_t currentDataPtrOffset = c.dstOffset ;
970
- size_t queryElementDataSize = (use64Version) ? sizeof (GLuint64) : sizeof (GLuint); // each query might write to multiple values/elements
953
+ IQueryPool::E_QUERY_TYPE queryType = qp->getCreationParameters ().queryType ;
954
+ bool use64Version = c.flags .hasValue (IQueryPool::E_QUERY_RESULTS_FLAGS::EQRF_64_BIT);
955
+ bool availabilityFlag = c.flags .hasValue (IQueryPool::E_QUERY_RESULTS_FLAGS::EQRF_WITH_AVAILABILITY_BIT);
956
+ bool waitForAllResults = c.flags .hasValue (IQueryPool::E_QUERY_RESULTS_FLAGS::EQRF_WAIT_BIT);
957
+ bool partialResults = c.flags .hasValue (IQueryPool::E_QUERY_RESULTS_FLAGS::EQRF_PARTIAL_BIT);
971
958
972
- GLenum pname;
973
- if (availabilityFlag)
974
- pname = GL_QUERY_RESULT_AVAILABLE;
975
- else if (waitForAllResults)
976
- pname = GL_QUERY_RESULT;
977
- else if (partialResults)
978
- pname = GL_QUERY_NO_WAIT;
959
+ assert (queryType == IQueryPool::E_QUERY_TYPE::EQT_OCCLUSION || queryType == IQueryPool::E_QUERY_TYPE::EQT_TIMESTAMP);
979
960
980
- auto getQueryBufferObject = [&](GLuint queryId, GLuint buffer, GLenum pname, GLintptr offset) -> void
981
- {
982
- if (use64Version)
961
+ if (c.firstQuery + c.queryCount > queryPoolQueriesCount)
983
962
{
984
- gl->extGlGetQueryBufferObjectui64v (queryId, buffer, pname, offset);
963
+ assert (false && " The sum of firstQuery and queryCount must be less than or equal to the number of queries in queryPool" );
964
+ break ;
985
965
}
986
- else
987
- {
988
- gl-> extGlGetQueryBufferObjectuiv (queryId, buffer, pname, offset) ;
966
+ if (partialResults && queryType == IQueryPool::E_QUERY_TYPE::EQT_TIMESTAMP) {
967
+ assert ( false && " QUERY_RESULT_PARTIAL_BIT must not be used if the pools queryType is QUERY_TYPE_TIMESTAMP. " );
968
+ break ;
989
969
}
990
- };
991
970
992
- for (uint32_t i = 0 ; i < c.queryCount ; ++i)
993
- {
994
- if (queryType == IQueryPool::E_QUERY_TYPE::EQT_TIMESTAMP || queryType == IQueryPool::E_QUERY_TYPE::EQT_OCCLUSION)
971
+ size_t currentDataPtrOffset = c.dstOffset ;
972
+ const uint32_t glQueriesPerQuery = qp->getGLQueriesPerQuery ();
973
+ const size_t queryElementDataSize = (use64Version) ? sizeof (GLuint64) : sizeof (GLuint); // each query might write to multiple values/elements
974
+ const size_t eachQueryDataSize = queryElementDataSize * glQueriesPerQuery;
975
+ const size_t eachQueryWithAvailabilityDataSize = (availabilityFlag) ? queryElementDataSize + eachQueryDataSize : eachQueryDataSize;
976
+
977
+ const size_t bufferDataSize = buffer->getSize ();
978
+
979
+ assert (core::is_aligned_to (c.dstOffset , queryElementDataSize));
980
+ assert (c.stride >= eachQueryWithAvailabilityDataSize);
981
+ assert (c.stride && core::is_aligned_to (c.stride , eachQueryWithAvailabilityDataSize)); // stride must be aligned to each query data size considering the specified flags
982
+ assert ((bufferDataSize - currentDataPtrOffset) >= (c.queryCount * c.stride )); // bufferDataSize is not enough for "queryCount" queries and specified stride
983
+ assert ((bufferDataSize - currentDataPtrOffset) >= (c.queryCount * eachQueryWithAvailabilityDataSize)); // bufferDataSize is not enough for "queryCount" queries with considering the specified flags
984
+
985
+ auto getQueryObject = [&](GLuint queryId, GLuint buffer, GLenum pname, GLintptr offset, uint32_t queueIdx) -> void
995
986
{
996
- assert (queryPoolQueriesCount == queriesRange.size ());
997
- assert (c.stride >= queryElementDataSize);
998
- GLuint query = queries[i+c.firstQuery ];
987
+ assert (ctxid == queueIdx);
988
+ if (ctxid == queueIdx)
989
+ {
990
+ if (use64Version)
991
+ gl->extGlGetQueryBufferObjectui64v (queryId, buffer, pname, offset);
992
+ else
993
+ gl->extGlGetQueryBufferObjectuiv (queryId, buffer, pname, offset);
994
+ }
995
+ };
999
996
1000
- getQueryBufferObject (query, bufferId, pname, currentDataPtrOffset);
1001
- }
1002
- else
997
+ // iterate on each query
998
+ for (uint32_t i = 0 ; i < c.queryCount ; ++i)
1003
999
{
1004
- assert (false && " QueryType is not supported." );
1005
- }
1000
+ if (currentDataPtrOffset >= bufferDataSize)
1001
+ {
1002
+ assert (false );
1003
+ break ;
1004
+ }
1005
+
1006
+ const size_t queryDataOffset = currentDataPtrOffset;
1007
+ const size_t availabilityDataOffset = queryDataOffset + eachQueryDataSize; // Write Availability to this offset if flag specified
1008
+
1009
+ // iterate on each gl query (we may have multiple gl queries per query like pipelinestatistics query type)
1010
+ const uint32_t queryIndex = i + c.firstQuery ;
1011
+ const uint32_t glQueryBegin = queryIndex * glQueriesPerQuery;
1012
+ bool allGlQueriesAvailable = true ;
1013
+ for (uint32_t q = 0 ; q < glQueriesPerQuery; ++q)
1014
+ {
1015
+ const size_t subQueryDataOffset = queryDataOffset + q * queryElementDataSize;
1016
+ const uint32_t queryIdx = glQueryBegin + q;
1017
+ const uint32_t lastQueueToUse = qp->getLastQueueToUseForQuery (queryIdx);
1018
+ GLuint query = qp->getQueryAt (lastQueueToUse, queryIdx);
1019
+
1020
+ GLenum pname;
1021
+ if (waitForAllResults)
1022
+ {
1023
+ // Has WAIT_BIT -> Get Result with Wait (GL_QUERY_RESULT) + don't getQueryAvailability (if availability flag is set it will report true)
1024
+ pname = GL_QUERY_RESULT;
1025
+ }
1026
+ else if (partialResults)
1027
+ {
1028
+ // Has PARTIAL_BIT but no WAIT_BIT -> (read vk spec) -> result value between zero and the final result value
1029
+ // No PARTIAL queries for GL -> GL_QUERY_RESULT_NO_WAIT best match
1030
+ pname = GL_QUERY_RESULT_NO_WAIT;
1031
+ }
1032
+ else if (availabilityFlag)
1033
+ {
1034
+ // Only Availablity -> Get Results with NoWait + get Query Availability
1035
+ pname = GL_QUERY_RESULT_NO_WAIT;
1036
+ }
1037
+ else
1038
+ {
1039
+ // No Flags -> GL_QUERY_RESULT_NO_WAIT
1040
+ pname = GL_QUERY_RESULT_NO_WAIT;
1041
+ }
1042
+
1043
+ if (availabilityFlag && !waitForAllResults && (q == glQueriesPerQuery - 1 ))
1044
+ getQueryObject (query, bufferId, GL_QUERY_RESULT_AVAILABLE, availabilityDataOffset, lastQueueToUse);
1006
1045
1007
- currentDataPtrOffset += c.stride ;
1046
+ getQueryObject (query, bufferId, pname, subQueryDataOffset, lastQueueToUse);
1047
+
1048
+ if (availabilityFlag && waitForAllResults && (q == glQueriesPerQuery - 1 ))
1049
+ getQueryObject (query, bufferId, GL_QUERY_RESULT_AVAILABLE, availabilityDataOffset, lastQueueToUse);
1050
+ }
1051
+
1052
+ currentDataPtrOffset += c.stride ;
1053
+ }
1008
1054
}
1009
1055
}
1010
1056
break ;
1011
1057
case impl::ECT_WRITE_TIMESTAMP:
1012
1058
{
1013
1059
auto & c = cmd.get <impl::ECT_WRITE_TIMESTAMP>();
1014
1060
const COpenGLQueryPool* qp = static_cast <const COpenGLQueryPool*>(c.queryPool .get ());
1015
- const GLuint query = qp->getQueryAt (c.query );
1016
- assert (qp->getCreationParameters ().queryType == IQueryPool::E_QUERY_TYPE::EQT_TIMESTAMP);
1017
- gl->glQuery .pglQueryCounter (query, GL_TIMESTAMP);
1061
+ qp->writeTimestamp (gl, ctxid, c.query );
1018
1062
}
1019
1063
break ;
1020
1064
case impl::ECT_BIND_DESCRIPTOR_SETS:
0 commit comments